Ejemplo n.º 1
0
def find_peak(x, y, ref, sam, pro_max=1, pro_min=1, threshold=0.1, except_around=None):
    if except_around is not None and len(except_around) != 2:
        raise ValueError("Invalid except_around arg. Try [start, stop].")
    if except_around is not None:
        try:
            float(except_around[0])
            float(except_around[1])
        except ValueError:
            raise ValueError(
                "Invalid except_around arg. Only numeric values are allowed."
            )
    x, y = _handle_input(x, y, ref, sam)
    max_indexes, _ = find_peaks(y, prominence=pro_max)
    y_rec = 1 / y
    min_indexes, _ = find_peaks(y_rec, prominence=pro_min)
    min_idx = []
    max_idx = []
    for idx in max_indexes:
        if _between(x[idx], except_around) or np.abs(y[idx]) > threshold:
            max_idx.append(idx)
    for idx in min_indexes:
        if _between(x[idx], except_around) or np.abs(y[idx]) > threshold:
            min_idx.append(idx)

    if len(x[max_idx]) != len(y[max_idx]) or len(x[min_idx]) != len(y[min_idx]):
        raise ValueError("Something went wrong, try to cut the edges of data.")

    return x[max_idx], y[max_idx], x[min_idx], y[min_idx]
Ejemplo n.º 2
0
def cwt(x, y, ref, sam, widths, floor_thres=0.1):
    x, y = _handle_input(x, y, ref, sam)
    idx = find_peaks_cwt(y, widths=widths)
    if _maybe_increase_before_cwt(y, tolerance=floor_thres):
        y += 2
    y_rec = 1 / y
    idx2 = find_peaks_cwt(y_rec, widths=widths)
    return x[idx], y[idx] - 2, x[idx2], y[idx2] - 2
Ejemplo n.º 3
0
def convolution(x, y, ref, sam, win_len, standev=200):
    x, y = _handle_input(x, y, ref, sam)
    if win_len < 0 or win_len > len(x):
        raise ValueError("Window length must be 0 < window_length < len(x)")

    xint, yint = interpolate_data(x, y, [], [])
    window = gaussian(win_len, std=standev)
    smoothed = convolve(yint, window / window.sum(), mode="same")
    return xint, smoothed
Ejemplo n.º 4
0
def cut_data(x, y, ref, sam, start=None, stop=None):
    x, y = _handle_input(x, y, ref, sam)
    if start is None:
        start = np.min(x)
    if stop is None:
        stop = np.max(x)
    if start < stop:
        low_item, _ = find_nearest(x, start)
        high_item, _ = find_nearest(x, stop)
        mask = np.where((x >= low_item) & (x <= high_item))
        return x[mask], y[mask]
    elif stop < start:
        raise ValueError("Start must not exceed stop value.")
    else:
        return np.array([]), np.array([])
Ejemplo n.º 5
0
def savgol(x, y, ref, sam, window=101, order=3):
    x, y = _handle_input(x, y, ref, sam)
    xint, yint = interpolate_data(x, y, [], [])
    if window > order:
        try:
            if window % 2 == 1:
                fil = savgol_filter(yint, window_length=window, polyorder=order)
                return xint, fil
            else:
                fil = savgol_filter(yint, window_length=window + 1, polyorder=order)
                return xint, fil
        except Exception as e:
            print(e)
    else:
        raise ValueError("Order must be lower than window length.")
Ejemplo n.º 6
0
def cff_method(x, y, ref, sam, ref_point=0, p0=None, maxtries=8000):
    """
    Phase modulated cosine function fit method.

    Parameters
    ----------
    x: array-like
        x-axis data
    y: array-like
        y-axis data
    ref, sam: array-like
        the reference and sample arm spectra evaluated at x
    p0: array-like
        the initial parameters for fitting

    Returns
    -------
    dispersion: array-like
        [GD, GDD, TOD, FOD, QOD]
    bf: array-like
        best fitting curve
    """
    if p0 is None:
        p0 = [1, 1, 1, 1, 1, 1, 1, 1, 1]

    x, y = _handle_input(x, y, ref, sam)

    try:
        orderhelper = np.max(np.flatnonzero(p0)) - 2

        p0 = np.trim_zeros(p0, "b")

        _funct = _cosfit_config[orderhelper]

        popt, pcov = curve_fit(_funct, x - ref_point, y, p0, maxfev=maxtries)

        dispersion = np.zeros_like(popt)[:-3]
        for num in range(len(popt) - 3):
            dispersion[num] = popt[num + 3] * factorial(num + 1)
        return dispersion, _funct(x - ref_point, *popt)
    except RuntimeError:
        raise ValueError(f"""Max tries ({maxtries}) reached..
                             Parameters could not be estimated.""")
Ejemplo n.º 7
0
 def test_input_handling5(self):
     with self.assertRaises(ValueError):
         _handle_input([], self.y, [], [])
Ejemplo n.º 8
0
 def test_input_handling4(self):
     with self.assertRaises(ValueError):
         _handle_input(self.x, [], [], [])
Ejemplo n.º 9
0
 def test_input_handling3(self):
     x, y = _handle_input(self.x, self.y, self.ref, [])
     np.testing.assert_array_equal(x, self.x)
     np.testing.assert_array_equal(y, self.y)
Ejemplo n.º 10
0
def min_max_method(
    x,
    y,
    ref,
    sam,
    ref_point,
    maxx=None,
    minx=None,
    SPP_callbacks=None,
):
    """
    Build the phase from extremal positions and SPP_callbacks.
    """
    x, y = _handle_input(x, y, ref, sam)
    if maxx is None:
        max_ind = argrelextrema(y, np.greater)
        maxx = x[max_ind]
    if minx is None:
        min_ind = argrelextrema(y, np.less)
        minx = x[min_ind]

    _, ref_index = find_nearest(x, ref_point)
    ref_point = x[ref_index]
    logger.info(f"refpoint set to {x[ref_index]} instead of {ref_point}.")

    # subtract the reference point from x axis at extremals
    max_freq = x[ref_index] - maxx
    min_freq = x[ref_index] - minx

    if SPP_callbacks is not None:
        if isinstance(SPP_callbacks, numbers.Number):
            SPP_callbacks -= ref_point
        elif isinstance(SPP_callbacks, (list, np.ndarray)):
            try:
                SPP_callbacks = np.asarray(SPP_callbacks) - ref_point
            except TypeError:
                pass
        else:
            raise TypeError("SPP_callbacks must be list-like, or number.")
        logger.info(
            f"SPP_callbacks are now {SPP_callbacks}, with ref_point {ref_point}."
        )

    # find which extremal point is where (relative to reference_point) and order them
    # as they need to be multiplied together with the corresponding order `m`
    neg_freq = np.sort(
        np.append(max_freq[max_freq < 0], min_freq[min_freq < 0]))[::-1]
    pos_freq = np.sort(
        np.append(max_freq[max_freq >= 0], min_freq[min_freq >= 0]))

    pos_data_x, pos_data_y = _build_single_phase_data(
        -pos_freq, SPP_callbacks=SPP_callbacks)

    # if we fail, the whole negative half is empty
    try:
        if np.diff(pos_data_y)[-1] < 0:
            flip = True
            logger.info(
                "Positive side was flipped because the other side is decreasing."
            )
        else:
            flip = False
    except IndexError:
        flip = False

    neq_data_x, neq_data_y = _build_single_phase_data(
        -neg_freq, SPP_callbacks=SPP_callbacks, flip=flip)

    x_s = np.insert(neq_data_x, np.searchsorted(neq_data_x, pos_data_x),
                    pos_data_x)
    y_s = np.insert(neq_data_y, np.searchsorted(neq_data_x, pos_data_x),
                    pos_data_y)

    return x_s + ref_point, -y_s + ref_point
Ejemplo n.º 11
0
def interpolate_data(x, y, ref, sam):
    x, y = _handle_input(x, y, ref, sam)
    xint = np.linspace(x[0], x[-1], len(x))
    intp = interp1d(x, y, kind="linear")
    yint = intp(xint)
    return xint, yint