Ejemplo n.º 1
0
def calc_flatten_matrix(flatten: FlattenOrStr,
                        stereo_nchan: int) -> np.ndarray:
    """Raises CorrError on invalid input.

    If flatten is Flatten.Stereo, returns shape=(nchan,nchan) identity matrix.
    - (N,nchan) @ (nchan,nchan) = (N,nchan).

    Otherwise, returns shape=(nchan) flattening matrix.
    - (N,nchan) @ (nchan) = (N)

    https://docs.scipy.org/doc/numpy/reference/generated/numpy.matmul.html#numpy.matmul
    '''
    If the second argument is 1-D,
    it is promoted to a matrix by appending a 1 to its dimensions.
    After matrix multiplication the appended 1 is removed."
    '''
    """

    if flatten is Flatten.Stereo:
        # 2D identity (results in 2-dim data)
        flatten_matrix = np.eye(stereo_nchan, dtype=FLOAT)

    # 1D (results in 1-dim data)
    elif flatten is Flatten.SumAvg:
        flatten_matrix = np.ones(stereo_nchan, dtype=FLOAT) / stereo_nchan

    elif flatten is Flatten.DiffAvg:
        flatten_matrix = calc_flatten_matrix(str(flatten), stereo_nchan)
        flatten_matrix = rightpad(flatten_matrix, stereo_nchan, 0)

    else:
        words = flatten.replace(",", " ").split()
        try:
            flatten_matrix = np.array([FLOAT(word) for word in words])
        except ValueError as e:
            raise CorrError("Invalid stereo flattening matrix") from e

        flatten_abs_sum = np.sum(np.abs(flatten_matrix))
        if flatten_abs_sum == 0:
            raise CorrError(
                "Stereo flattening matrix must have nonzero elements")

        flatten_matrix /= flatten_abs_sum

    assert flatten_matrix.dtype == FLOAT, flatten_matrix.dtype
    return flatten_matrix
Ejemplo n.º 2
0
    def _calc_lag_prevention(self) -> np.ndarray:
        """ Returns input-data window,
        which zeroes out all data older than 1-ish frame old.
        See https://github.com/jimbo1qaz/corrscope/wiki/Correlation-Trigger
        """
        N = self._buffer_nsamp
        halfN = N // 2

        # - Create a cosine taper of `width` <= 1 frame
        # - Right-pad(value=1, len=1 frame)
        # - Place in left half of N-sample buffer.

        # To avoid cutting off data, use a narrow transition zone (invariant to stride).
        lag_prevention = self.cfg.lag_prevention
        tsamp_frame = self._tsamp_frame
        transition_nsamp = round(tsamp_frame *
                                 lag_prevention.transition_frames)

        # Left half of a Hann cosine taper
        # Width (type=subsample) = min(frame * lag_prevention, 1 frame)
        assert transition_nsamp <= tsamp_frame
        width = transition_nsamp
        taper = windows.hann(width * 2)[:width]

        # Right-pad=1 taper to lag_prevention.max_frames long [t-#*f, t]
        taper = rightpad(taper,
                         iround(tsamp_frame * lag_prevention.max_frames))

        # Left-pad=0 taper to left `halfN` of data_taper [t-halfN, t]
        taper = leftpad(taper, halfN)

        # Generate left half-taper to prevent correlating with 1-frame-old data.
        # Right-pad=1 taper to [t-halfN, t-halfN+N]
        # TODO switch to rightpad()? Does it return FLOAT or not?
        data_taper = np.ones(N, dtype=FLOAT)
        data_taper[:halfN] = np.minimum(data_taper[:halfN], taper)

        return data_taper