Esempio n. 1
0
def _find_primary_bounds(x, dS_mask, ddS_mask, min_distance, is_absorption):
    prime_regions = OrderedDict()

    # Find obvious lines by peak values.
    for pind in np.where(dS_mask)[0][::2]:
        lower_ind = find_nearest(
            np.ma.array(x.value, mask=~ddS_mask | (x.value > x.value[pind])),
            x.value[pind])
        upper_ind = find_nearest(
            np.ma.array(x.value, mask=~ddS_mask | (x.value < x.value[pind])),
            x.value[pind])

        lower_x_ddS, upper_x_ddS = x.value[lower_ind], \
                                   x.value[upper_ind]
        x_dS = x[pind]

        # if is_absorption:
        #     cond = np.sign(ddS[lower_ind]) > np.sign(ddS[upper_ind])
        # else:
        #     cond = np.sign(ddS[lower_ind]) < np.sign(ddS[upper_ind])

        # if cond:
        # Ensure that this found peak value is not within the minimum
        # distance of any other found peak values.
        if np.all([
                np.abs(x - x_dS) > min_distance
                for x, _, _, _ in prime_regions.values()
        ]):
            prime_regions[(lower_ind, upper_ind)] = (x_dS, (lower_x_ddS,
                                                            upper_x_ddS),
                                                     is_absorption, False)

    return prime_regions
Esempio n. 2
0
def _find_ternary_bounds(x, ddS_mask, dddS_mask, min_distance, is_absorption):
    ternary_regions = OrderedDict()

    # Find "buried" lines. Do this by taking the third difference of the
    # spectrum. Find the indices where the dddS_mask is true, retrieve only a
    # single index from the tuple by going in steps of 2. Each tind represents
    # the index of the centroid of the found buried line.
    for tind in np.where(dddS_mask)[0][::2]:
        # ddS contains bounds information. Find the lower bound index of the
        # dispersion.
        lower_ind = find_nearest(
            np.ma.array(x.value, mask=~ddS_mask | (x.value > x.value[tind])),
            x.value[tind])
        # ddS contains bounds information. Find the upper bound index of the
        # dispersion.
        upper_ind = find_nearest(
            np.ma.array(x.value, mask=~ddS_mask | (x.value < x.value[tind])),
            x.value[tind])

        # Retrieve the dispersion value for these indices and set the
        # dispersion value for the centroid.
        lower_x_ddS, upper_x_ddS = x.value[lower_ind], \
                                     x.value[upper_ind]

        if lower_ind == 0 or upper_ind == x.size - 1:
            continue

        x_dddS = x[tind]

        # if is_absorption:
        #     # This is truly a buried line if, for absorption, if the sign of
        #     # the lower index in the bounds mask is greater than the upper.
        #     cond = (dddS[lower_ind] > dddS[upper_ind])
        # else:
        #     # This is truly a buried line if, for emission, if the sign of
        #     # the lower index in the bounds mask is greater than the upper.
        #     cond = (dddS[lower_ind] < dddS[upper_ind])

        # if True:
        # Ensure that this found peak value is not within the minimum
        # distance of any other found peak values.
        if np.all([
                np.abs(x - x_dddS) > min_distance
                for x, _, _, _ in ternary_regions.values()
        ]):
            ternary_regions[(lower_ind, upper_ind)] = (x_dddS, (lower_x_ddS,
                                                                upper_x_ddS),
                                                       is_absorption, True)

    return ternary_regions
Esempio n. 3
0
def region_bounds(x, y, threshold=0.001, min_distance=1):
    # Slice the y axis in half -- if more data elements exist in the "top"
    # half, assume the spectrum is absorption. Otherwise, assume emission.
    is_absorption = profile_type(x, y) == 'absorption'

    if not isinstance(min_distance, u.Quantity):
        min_distance *= x.unit

    dY, ddY, dddY = _make_data_diffs(y)
    dS, ddS, dddS = _make_sign_diffs(dY, ddY, dddY)

    dS_mask, ddS_mask, dddS_mask = _generate_masks(y, threshold, dS, ddS, dddS,
                                                   is_absorption)

    ternary_regions = _find_ternary_bounds(x, ddS_mask, dddS_mask,
                                           min_distance, is_absorption)
    prime_regions = _find_primary_bounds(x, dS_mask, ddS_mask, min_distance,
                                         is_absorption)

    # Delete any information in ternary that shares the same bounds in primary
    for k in prime_regions:
        if k in ternary_regions:
            del ternary_regions[k]

    # For the ternary centroids closest to a prime centroid, use the bounds
    # information of the primary centroid
    for (t_low_ind, t_up_ind), (t_cent, bnds, is_absorb,
                                buried) in ternary_regions.copy().items():
        p_cents = [pr[0] for pr in prime_regions.values()]
        p_bnds = [(lo, hi) for lo, hi in prime_regions]

        # Find closest index
        ind = find_nearest(np.array([c.value for c in p_cents]), t_cent.value)
        p_cent = p_cents[ind]
        p_bnd = p_bnds[ind]
        # p_ind = find_nearest(x.value, p_cent.value)

        new_t_up_ind = t_up_ind
        new_t_low_ind = t_low_ind

        # If the prime centroid is greater than the ternary centroid,
        # update the ternary upper bound.
        if p_cent > t_cent:
            new_t_up_ind = p_bnd[1]  # p_ind
        else:
            new_t_low_ind = p_bnd[0]  # p_ind

        del ternary_regions[(t_low_ind, t_up_ind)]

        ternary_regions[(new_t_low_ind,
                         new_t_up_ind)] = (t_cent, (x.value[new_t_low_ind],
                                                    x.value[new_t_up_ind]),
                                           is_absorb, buried)

    ternary_regions.update(prime_regions)

    return ternary_regions