예제 #1
0
    def batchreconstructcompact(self, img):
        nim = img.shape[0]
        r = np.mod(nim, 6)
        if r > 0:  # pad with empty frames so total number of frames is divisible by 6
            img = np.concatenate((img, np.zeros((6 - r, self.N, self.N), np.single)))
            nim = nim + 6 - r
        nim3 = nim // 3
        imf = fft.rfft2(img) * self._prefilter[:, 0:self.N // 2 + 1]
        img2 = np.zeros([nim, 2 * self.N, 2 * self.N], dtype=np.single)
        for i in range(0, nim, 3):
            self._carray1[:, 0:self.N // 2, 0:self.N // 2 + 1] = imf[i:i + 3, 0:self.N // 2, 0:self.N // 2 + 1]
            self._carray1[:, 3 * self.N // 2:2 * self.N, 0:self.N // 2 + 1] = imf[i:i + 3, self.N // 2:self.N,
                                                                              0:self.N // 2 + 1]
            img2[i:i + 3, :, :] = fft.irfft2(self._carray1) * self._reconfactor
        res = np.zeros((nim3, 2 * self.N, 2 * self.N), dtype=np.single)

        imgf = fft.rfft(img2[:, :self.N, :self.N], nim, 0)[:nim3 // 2 + 1, :, :]
        res[:, :self.N, :self.N] = fft.irfft(imgf, nim3, 0)
        imgf = fft.rfft(img2[:, :self.N, self.N:2 * self.N], nim, 0)[:nim3 // 2 + 1, :, :]
        res[:, :self.N, self.N:2 * self.N] = fft.irfft(imgf, nim3, 0)
        imgf = fft.rfft(img2[:, self.N:2 * self.N, :self.N], nim, 0)[:nim3 // 2 + 1, :, :]
        res[:, self.N:2 * self.N, :self.N] = fft.irfft(imgf, nim3, 0)
        imgf = fft.rfft(img2[:, self.N:2 * self.N, self.N:2 * self.N], nim, 0)[:nim3 // 2 + 1, :, :]
        res[:, self.N:2 * self.N, self.N:2 * self.N] = fft.irfft(imgf, nim3, 0)

        res = fft.irfft2(fft.rfft2(res) * self._postfilter[:, :self.N + 1])
        return res
예제 #2
0
    def seek_record_read(self, offset, size):
        if offset % self.recordsize != 0 or size % self.recordsize != 0:
            raise ValueError(
                "size and offset must be an integer number of records")

        raw = self.fh_raw.seek_record_read(offset, size)

        if self.npol == 2 and self._raw_data_class == AROCHIMERawData:
            raw = raw.view(raw.dtype.fields.values()[0][0])

        raw = raw.reshape(-1, self.fh_raw.nchan, self.npol)
        nyq_pad = np.zeros((raw.shape[0], 1, self.npol), dtype=raw.dtype)
        raw = np.concatenate((raw, nyq_pad), axis=1)
        # Get pseudo-timestream
        pd = irfft(raw, axis=1, **_rfftargs)
        # Set up for deconvolution
        fpd = rfft(pd, axis=0, **_rfftargs)
        del pd
        if self.fh is None or self.fh.shape[0] != fpd.shape[0]:
            lh = np.zeros((raw.shape[0], self.h.shape[1]))
            lh[:self.h.shape[0]] = self.h
            self.fh = rfft(lh, axis=0, **_rfftargs).conj()
            del lh
        # FT of Wiener deconvolution kernel
        fg = self.fh.conj() / (np.abs(self.fh)**2 + (1 / self.sn)**2)
        # Deconvolve and get deconvolved timestream
        rd = irfft(fpd * fg[..., np.newaxis], axis=0,
                   **_rfftargs).reshape(-1, self.npol)
        # select actual part requested
        self.offset = offset + size
        # view as a record array
        return rd.astype('f4')
예제 #3
0
    def seek_record_read(self, offset, size):
        if offset % self.recordsize != 0 or size % self.recordsize != 0:
            raise ValueError("size and offset must be an integer number of records")

        raw = self.fh_raw.seek_record_read(offset, size)

        if self.npol == 2 and self._raw_data_class == AROCHIMERawData:
            raw = raw.view(raw.dtype.fields.values()[0][0])

        raw = raw.reshape(-1, self.fh_raw.nchan, self.npol)
        nyq_pad = np.zeros((raw.shape[0], 1, self.npol), dtype=raw.dtype)
        raw = np.concatenate((raw, nyq_pad), axis=1)
        # Get pseudo-timestream
        pd = irfft(raw, axis=1, **_rfftargs)
        # Set up for deconvolution
        fpd = rfft(pd, axis=0, **_rfftargs)
        del pd
        if self.fh is None or self.fh.shape[0] != fpd.shape[0]:
            lh = np.zeros((raw.shape[0], self.h.shape[1]))
            lh[:self.h.shape[0]] = self.h
            self.fh = rfft(lh, axis=0, **_rfftargs).conj()
            del lh
        # FT of Wiener deconvolution kernel
        fg = self.fh.conj() / (np.abs(self.fh)**2 + (1/self.sn)**2)
        # Deconvolve and get deconvolved timestream
        rd = irfft(fpd * fg[..., np.newaxis],
                          axis=0, **_rfftargs).reshape(-1, self.npol)
        # select actual part requested
        self.offset = offset + size
        # view as a record array
        return rd.astype('f4')
예제 #4
0
    def read(self, samples):

        raw = self.fh.read(samples)
        raw = np.swapaxes(raw, 1, 2)

        nyq_pad = np.zeros((raw.shape[0], 1, self.npol), dtype=raw.dtype)
        raw = np.concatenate((raw, nyq_pad), axis=1)

        # Get pseudo-timestream
        pd = irfft(raw, axis=1)
        # Set up for deconvolution
        fpd = rfft(pd, axis=0)
        del pd

        lh = np.zeros((raw.shape[0], self.h.shape[1]))
        lh[:self.h.shape[0]] = self.h
        fh = rfft(lh, axis=0).conj()
        del lh

        # FT of Wiener deconvolution kernel
        fg = fh.conj() / (np.abs(fh)**2 + (1 / self.sn)**2)
        # Deconvolve and get deconvolved timestream
        rd = irfft(fpd * fg[..., np.newaxis], axis=0).reshape(-1, self.npol)

        # view as a record array
        return rd.astype('f4')
예제 #5
0
    def read(self, samples):

        raw = self.fh.read(samples)
        raw = np.swapaxes(raw, 1, 2)

        nyq_pad = np.zeros((raw.shape[0], 1, self.npol), dtype=raw.dtype)
        raw = np.concatenate((raw, nyq_pad), axis=1)
 
        # Get pseudo-timestream
        pd = irfft(raw, axis=1)
        # Set up for deconvolution
        fpd = rfft(pd, axis=0)
        del pd

        lh = np.zeros((raw.shape[0], self.h.shape[1]))
        lh[:self.h.shape[0]] = self.h
        fh = rfft(lh, axis=0).conj()
        del lh
        
        # FT of Wiener deconvolution kernel
        fg = fh.conj() / (np.abs(fh)**2 + (1/self.sn)**2)
        # Deconvolve and get deconvolved timestream
        rd = irfft(fpd * fg[..., np.newaxis],
                          axis=0).reshape(-1, self.npol)

        # view as a record array
        return rd.astype('f4')
예제 #6
0
def plotGottleibShuNoise(length, signalFunc, numSeries=16):
    source = signalFunc(length, numSeries)
    suppressed, g_hat = gottliebShu(source, numSeries)
    regibbsed = spectralLowpass(suppressed, numSeries)

    plot(
        source,
        suppressed,
        regibbsed,
        'Filtered result',
        'result_gottleibShu_' + signalFunc.__name__ + '.png',
    )

    # Plot spectrum.
    source_spec = rfft(source)[0:numSeries + 1]
    regibbsed_spec = rfft(regibbsed)[0:numSeries + 1]
    source_power = numpy.abs(source_spec)
    regibbsed_power = numpy.abs(regibbsed_spec)
    source_phase = numpy.angle(source_spec)
    regibbsed_phase = numpy.angle(regibbsed_spec)

    fig = pyplot.figure(figsize=(8, 6))

    ax11 = fig.add_subplot(221)
    ax11.set_title('Signal power')
    ax11.grid()
    ax11.plot(source_power)

    ax21 = fig.add_subplot(222)
    ax21.set_title('Signal phase')
    ax21.grid()
    ax21.set_ylim(-numpy.pi, numpy.pi)
    ax21.plot(source_phase)

    ax12 = fig.add_subplot(223)
    ax12.set_title('Filtered result power')
    ax12.grid()
    ax12.plot(regibbsed_power)

    ax22 = fig.add_subplot(224)
    ax22.set_title('Filtered result phase')
    ax22.grid()
    ax22.set_ylim(-numpy.pi, numpy.pi)
    ax22.plot(regibbsed_phase)

    fig.tight_layout()
    fig.savefig('spectrum_comparison_' + signalFunc.__name__ + '.png')
    pyplot.close()
예제 #7
0
    def display_radMUSIC(self,
                         frequency,
                         npoints=360,
                         signals=1,
                         shw=True,
                         block_run=False):
        """Display a polar plot of estimated DOA using the MUSIC algorithm

        Arguments:
            frequency (float): The frequency to use for the MUSIC calculation.
            npoints (int): The total number of points around the circle at which to evaluate.
            signals (int): The numbers of signals to locate.
            shw (bool): Show the plot? If False, will return the data that was to be plotted.
            block_run (bool): Pause execution of the file while the figure is open? Set to True for running in the command-line.
        """

        X = 2 * np.pi * np.arange(start=0, stop=npoints) / npoints
        self.dataFFT = fft_pack.rfft(self.data,
                                     axis=0,
                                     n=2 * self.data.shape[0])
        pos = fft_pack.rfftfreq(2 * self.data.shape[0]) * self.sample_rate
        actidx = np.argmin(abs(pos - frequency))
        cors, _ = self._MUSIC1D_((pos[actidx], actidx), X, numsignals=signals)

        if shw:
            plt.figure()
            ax = plt.subplot(111, projection='polar')
            ax.plot(X, cors)
            ax.set_title("Estimated Acoustic Source Direction")
            plt.show(block=block_run)
        else:
            return cors
예제 #8
0
def ir2fr(ir, fs, N=None):
    """
    Convert impulse response into frequency response. Returns single-sided RMS spectrum.

    :param ir: Impulser response
    :param fs: Sample frequency
    :param N: Blocks

    Calculates the positive frequencies using :func:`np.fft.rfft`.
    Corrections are then applied to obtain the single-sided spectrum.

    .. note:: Single-sided spectrum. Therefore, the amount of bins returned is either N/2 or N/2+1.

    """
    #ir = ir - np.mean(ir) # Remove DC component.

    N = N if N else ir.shape[-1]
    fr = rfft(ir, n=N) / N
    f = np.fft.rfftfreq(N, 1.0 / fs)  #/ 2.0

    fr *= 2.0
    fr[..., 0] /= 2.0  # DC component should not be doubled.
    if not N % 2:  # if not uneven
        fr[..., -1] /= 2.0  # And neither should fs/2 be.

    #f = np.arange(0, N/2+1)*(fs/N)

    return f, fr
예제 #9
0
def ir2fr(ir, fs, N=None):
    """
    Convert impulse response into frequency response. Returns single-sided RMS spectrum.
    
    :param ir: Impulser response
    :param fs: Sample frequency
    :param N: Blocks
    
    Calculates the positive frequencies using :func:`np.fft.rfft`.
    Corrections are then applied to obtain the single-sided spectrum.
    
    .. note:: Single-sided spectrum. Therefore, the amount of bins returned is either N/2 or N/2+1.
    
    """
    #ir = ir - np.mean(ir) # Remove DC component.
    
    N = N if N else ir.shape[-1]
    fr = rfft(ir, n=N) / N
    f = np.fft.rfftfreq(N, 1.0/fs)    #/ 2.0
    
    fr *= 2.0
    fr[..., 0] /= 2.0    # DC component should not be doubled.
    if not N%2: # if not uneven
        fr[..., -1] /= 2.0 # And neither should fs/2 be.
    
    #f = np.arange(0, N/2+1)*(fs/N)
    
    return f, fr
예제 #10
0
def compPhaseShifts4(y):

    try:
        sns.set_palette(sns.color_palette("husl", 20))
    except:
        pass

    fig, ax = lab.subplots()

    fft = fftw.rfft(y)
    shifts = np.arange(-np.pi, np.pi, 0.01)

    for tZero in range(310, 330):
        print tZero
        causalityRatio = []

        for i in range(0, len(shifts)):
            shiftedFFT = fftPhaseShift(fft, shifts[i])
            shifted = fftw.irfft(shiftedFFT)
            causalityRatio.append(
                np.sum(shifted[:tZero]**2) / np.sum(shifted[tZero:]**2))

        ax.plot(shifts, causalityRatio, label=tZero)

    ax.legend()
    fig.show()

    return
예제 #11
0
    def __call__(self, max_peak_count=None, max_peak_frequency=None, min_peak_frequency=None, proc_name=None):
        # from sasha import sasha_configuration
        try:
            with systemtools.Timer("\t{}: [{}] Computing RFFT:".format(proc_name, self.frame_id)):
                fft = rfft(self.windowed_audio)
            with systemtools.Timer("\t{}: [{}] Locating peaks:".format(proc_name, self.frame_id)):
                peaks = []
                mag = abs(fft)
                prev_mag = numpy.abs(mag[0])
                this_mag = numpy.abs(mag[1])
                next_mag = None
                for bin in range(2, len(mag) - 1):
                    next_mag = numpy.abs(mag[bin])
                    if prev_mag < this_mag and next_mag < this_mag:
                        frequency = (bin - 1) * self.fundamental
                        amplitude = this_mag
                        phase = numpy.angle(fft[bin - 1])
                        peak = Peak(frequency, amplitude, phase, frame_id=self.frame_id)
                        peaks.append(peak)
                    prev_mag = this_mag
                    this_mag = next_mag
                self._peaks = self._filter_peaks(
                    peaks,
                    max_peak_count=max_peak_count,
                    max_peak_frequency=max_peak_frequency,
                    min_peak_frequency=min_peak_frequency,
                )
                self._frequencies = tuple(_.frequency for _ in self)
                self._midis = tuple(_.midis for _ in self)
        except:
            import traceback

            traceback.print_exc()
예제 #12
0
def BasebandProcess(ar_data, band, SR, dt, N, DN, offset, i, dd_coh, ngate):
    print('ar_data', ar_data)
    fh = mark4.open(ar_data,
                    'rs',
                    ntrack=64,
                    decade=2010,
                    sample_rate=SR,
                    thread_ids=[2 * band, 2 * band + 1])
    fh.seek(offset + i * (N - DN))
    t0 = fh.tell(unit='time')
    print('t0', t0)
    t1 = t0.mjd
    print('t1', t1)
    print('N-DN', N - DN)
    print('dt', dt)
    print('ngate', ngate)
    # note ph is equilibrium to ((ph)*P0) / (P0/ngate) % ngate
    ph, ncycle = FindPhase(t0, N - DN, dt, ngate)
    ph %= ngate
    print('ph3', ph)
    z = fh.read(N)
    z = rfft(z, axis=0, **_fftargs)
    z *= dd_coh[..., np.newaxis]
    z = irfft(z, axis=0, **_fftargs)[:-DN]
    z = z.astype(np.float32)
    z = z * z
    return ph, z
예제 #13
0
def timePhaseShift(Y, shift):
    fft = fftw.rfft(Y)
    gainLin, phase = complexToGainAndPhase(fft)
    phase += shift
    #    phase[phase>=np.pi] -= np.pi
    #    phase[phase<=-np.pi] += np.pi
    fft = gainAndPhaseToComplex(gainLin, phase)
    outY = fftw.irfft(fft)
    return outY
예제 #14
0
def _shift(trace, shift):
    """Shift trace by given time and correct starttime => interpolation"""
    msg = ('interpolate trace %s with starttime %s to shift by %.6fs '
           '(Fourier method)')
    log.debug(msg, trace.id, trace.stats.starttime, shift)
    nfft = next_fast_len(len(trace))
    spec = rfft(trace.data, nfft)
    freq = rfftfreq(nfft, trace.stats.delta)
    spec *= np.exp(-2j * np.pi * freq * shift)
    trace.data = irfft(spec, nfft)[:len(trace)]
    trace.stats.starttime -= shift
    return trace
예제 #15
0
def correlation(graphA, graphB):
    """
    Takes in two EVENLY SAMPLED graphs, then does the cross correlation in
    fourier space

    NOTE: I need to roll this a bit! 
    Note to Note: Why?  to draw it away from zero?  Maybe no roll :(
    """

    #    fart,graphA = zeroPadEqual(np.arange(len(graphA)),graphA,len(graphA)*3)
    #    fart,graphB = zeroPadEqual(np.arange(len(graphB)),graphB,len(graphB)*3)

    fftA = fftw.rfft(np.array(graphA))
    fftB = fftw.rfft(np.array(graphB))

    xCorr = np.conj(fftA) * fftB

    iXCorr = fftw.irfft(xCorr)

    #    return np.roll(iXCorr,len(iXCorr)/2)
    return iXCorr
예제 #16
0
    def display_radMUSICchunked(self,
                                frequency,
                                npoints=360,
                                signals=1,
                                shw=True,
                                block_run=False,
                                chunks=10):
        """Display a polar plot of estimated DOA using the MUSIC algorithm

        Arguments:
            frequency (float): The frequency to use for the MUSIC calculation.
            npoints (int): The total number of points around the circle at which to evaluate.
            signals (int): The numbers of signals to locate.
            shw (bool): Show the plot? If False, will return the data that was to be plotted.
            block_run (bool): Pause execution of the file while the figure is open? Set to True for running in the command-line.
        """

        X = 2 * np.pi * np.arange(start=0, stop=npoints) / npoints

        tRxx = np.zeros((self.mics.shape[0], self.mics.shape[0]),
                        dtype='complex128')
        indices = [
            int(x) for x in np.linspace(
                0, self.data.shape[0], num=chunks + 1, endpoint=True)
        ]
        for mark in np.arange(len(indices) - 1):
            dcr = self.data[indices[mark]:indices[mark + 1], :]
            print(dcr.shape)
            ft = fft_pack.rfft(dcr, axis=0, n=2 * self.data.shape[0])
            pos = fft_pack.rfftfreq(2 * self.data.shape[0]) * self.sample_rate
            actidx = np.argmin(abs(pos - frequency))
            tRxx += np.dot(ft[actidx:actidx + 1].T,
                           np.conj(ft[actidx:actidx + 1]))
        tRxx /= chunks
        print(tRxx)

        # self.dataFFT = fft_pack.rfft(self.data, axis=0, n=2*self.data.shape[0])

        cors, _ = self._MUSIC1D_((pos[actidx], actidx),
                                 X,
                                 numsignals=signals,
                                 SI=tRxx)

        if shw:
            plt.figure()
            ax = plt.subplot(111, projection='polar')
            ax.plot(X, cors)
            ax.set_title("Estimated Acoustic Source Direction")
            plt.show(block=block_run)
        else:
            return cors
예제 #17
0
    def readPFB(self, samples):

        import timeit
        start_time = timeit.default_timer()

        raw = self.read(samples)
        raw = np.swapaxes(raw, 1, 2)

        nyq_pad = np.zeros((raw.shape[0], 1, self.npol), dtype=raw.dtype)
        raw = np.concatenate((raw, nyq_pad), axis=1)

        # Get pseudo-timestream
        pd = irfft(raw, axis=1)
        # Set up for deconvolution

        fpd = rfft(pd, axis=0)
        del pd

        #if not 'han' in self.__dict__ :
        lh = np.zeros((raw.shape[0], self.h.shape[1]))
        lh[:self.h.shape[0]] = self.h

        self.han = rfft(lh, axis=0).conj()
        del lh

        # FT of Wiener deconvolution kernel
        fg = self.han.conj() / (np.abs(self.han)**2 + (1 / self.sn)**2)
        print(fpd.shape)
        # Deconvolve and get deconvolved timestream
        rd = irfft(fpd * fg[..., np.newaxis], axis=0)
        print(rd.shape)

        rd = rd.reshape(-1, self.npol)

        print(timeit.default_timer() - start_time)

        # view as a record array
        return rd.astype('f4')
예제 #18
0
def render_plot():
    out_dir = "img"
    pathlib.Path(out_dir).mkdir(exist_ok=True)

    x = numpy.linspace(-1, 1, 512)
    rich = numpy.linspace(0, 1, 1201)
    rich = 0.5 - 3 * rich * rich

    plotter = Plotter(out_dir, int(len(x) / 2) + 1)

    for w in rich:
        data = normalize(mdadx10_sine(x, w))
        freq = to_decibel(rfft(data, planner_effort='FFTW_ESTIMATE'))
        plotter.plot(data, freq, x, w)
예제 #19
0
def makeCausalTime(y, tZero):
    """
    If you have the time series, this makes it easier (but slightly slower!
    Two more FFTS!)
    
    you have to provide the pulse (in bins)

    """

    fft = fftw.rfft(y)
    shifted = makeCausalFFT(fft, tZero)
    yOut = fftw.irfft(shifted)

    return yOut
예제 #20
0
def violet(N):
    """
    Violet noise. Power increases with 6 dB per octave. 
    
    :param N: Amount of samples.
    
    Power increases with +9 dB per octave.
    Power density increases with +6 dB per octave. 
    
    """
    x = np.random.randn(N)
    X = rfft(x) / N
    S = (np.arange(len(X)))# Filter
    y = (irfft(X*S)).real[0:N]
    return normalise(y)
예제 #21
0

        
예제 #22
0
def violet(N):
    """
    Violet noise. Power increases with 6 dB per octave. 
    
    :param N: Amount of samples.
    
    Power increases with +9 dB per octave.
    Power density increases with +6 dB per octave. 
    
    """
    x = np.random.randn(N)
    X = rfft(x) / N
    S = (np.arange(len(X)))  # Filter
    y = (irfft(X * S)).real[0:N]
    return normalise(y)
예제 #23
0
def brown(N):
    """
    Violet noise.
    
    :param N: Amount of samples.
    
    Power decreases with -3 dB per octave.
    Power density decreases with 6 dB per octave. 

    """
    x = np.random.randn(N)
    X = rfft(x) / N
    S = (np.arange(len(X))+1)# Filter
    y = (irfft(X/S)).real[0:N]
    return normalise(y)
예제 #24
0
def blue(N):
    """
    Blue noise. 
    
    :param N: Amount of samples.
    
    Power increases with 6 dB per octave.
    Power density increases with 3 dB per octave. 
    
    """
    x = np.random.randn(N)
    X = rfft(x) / N
    S = np.sqrt(np.arange(len(X)))  # Filter
    y = (irfft(X * S)).real[0:N]
    return normalise(y)
예제 #25
0
def blue(N):
    """
    Blue noise. 
    
    :param N: Amount of samples.
    
    Power increases with 6 dB per octave.
    Power density increases with 3 dB per octave. 
    
    """
    x = np.random.randn(N)
    X = rfft(x) / N
    S = np.sqrt(np.arange(len(X)))# Filter
    y = (irfft(X*S)).real[0:N]
    return normalise(y)
예제 #26
0
def brown(N):
    """
    Violet noise.
    
    :param N: Amount of samples.
    
    Power decreases with -3 dB per octave.
    Power density decreases with 6 dB per octave. 

    """
    x = np.random.randn(N)
    X = rfft(x) / N
    S = (np.arange(len(X)) + 1)  # Filter
    y = (irfft(X / S)).real[0:N]
    return normalise(y)
예제 #27
0
def violet(N: int) -> np.ndarray:
    """
    Violet noise. Power increases with 6 dB per octave.

    * N: Amount of samples.

    Power increases with +9 dB per octave.
    Power density increases with +6 dB per octave.

    https://github.com/python-acoustics
    """
    x = white(N)
    X = rfft(x) / N
    S = np.arange(X.size)  # Filter
    y = irfft(X * S).real[0:N]

    return normalise(y)
예제 #28
0
def apply_noise(y, target_snr_db=20):
    ## Adapted from: https://stackoverflow.com/questions/14058340/adding-noise-to-a-signal-in-python
    ## Apply random white noise to signal to reach target_snr_db

    x_watts = y ** 2
    sig_avg_watts = np.mean(x_watts)
    sig_avg_db = 10 * np.log10(sig_avg_watts)
    # Calculate noise according to [2] then convert to watts
    noise_avg_db = sig_avg_db - float(target_snr_db)
    noise_avg_watts = 10 ** (noise_avg_db / 10)
    # Generate an sample of white noise
    mean_noise = 0
    noise_volts = np.random.normal(mean_noise, noise_avg_watts, len(x_watts))
    Xb = rfft(noise_volts) / len(noise_volts)
    Sb = np.arange(Xb.size)+1  # Filter
    yb = irfft(Xb/Sb).real[:len(noise_volts)]
    # Noise up the original signal
    noisy_signal = y + yb

    return np.clip(noisy_signal, -1, 1)
예제 #29
0
    def batchreconstruct(self, img, n_output_frames=None):
        nim = img.shape[0]
        r = np.mod(nim, 14)
        if r > 0:  # pad with empty frames so total number of frames is divisible by 14
            img = np.concatenate((img, np.zeros((14 - r, self.N, self.N), np.single)))
            nim = nim + 14 - r
        imf = fft.rfft2(img) * self._prefilter[:, 0:self.N // 2 + 1]
        img2 = np.zeros([nim, 2 * self.N, 2 * self.N], dtype=np.single)
        for i in range(0, nim, 7):
            self._carray1[:, 0:self.N // 2, 0:self.N // 2 + 1] = imf[i:i + 7, 0:self.N // 2, 0:self.N // 2 + 1]
            self._carray1[:, 3 * self.N // 2:2 * self.N, 0:self.N // 2 + 1] = imf[i:i + 7, self.N // 2:self.N,
                                                                              0:self.N // 2 + 1]
            img2[i:i + 7, :, :] = fft.irfft2(self._carray1) * self._reconfactor

        nim7 = nim // 7
        if n_output_frames is None:
            n_output_frames = nim7

        img3 = fft.irfft(fft.rfft(img2, nim, 0)[0:nim7 // 2 + 1, :, :], n_output_frames, 0)
        res = fft.irfft2(fft.rfft2(img3) * self._postfilter[:, :self.N + 1])
        return res
예제 #30
0
def pink(N):
    """
    Pink noise. 
    
    :param N: Amount of samples.
    
    Pink noise has equal power in bands that are proportionally wide.
    Power density decreases with 3 dB per octave.
    
    """
    # This method uses the filter with the following coefficients.
    #b = np.array([0.049922035, -0.095993537, 0.050612699, -0.004408786])
    #a = np.array([1, -2.494956002, 2.017265875, -0.522189400])
    #return lfilter(B, A, np.random.randn(N))

    # Another way would be using the FFT
    x = np.random.randn(N)
    X = rfft(x) / N
    S = np.sqrt(np.arange(len(X)) + 1.)  # +1 to avoid divide by zero
    y = (irfft(X / S)).real[0:N]
    return normalise(y)
예제 #31
0
def pink(N):
    """
    Pink noise. 
    
    :param N: Amount of samples.
    
    Pink noise has equal power in bands that are proportionally wide.
    Power density decreases with 3 dB per octave.
    
    """
    # This method uses the filter with the following coefficients.
    #b = np.array([0.049922035, -0.095993537, 0.050612699, -0.004408786])
    #a = np.array([1, -2.494956002, 2.017265875, -0.522189400])
    #return lfilter(B, A, np.random.randn(N))
    
    # Another way would be using the FFT
    x = np.random.randn(N)
    X = rfft(x) / N
    S = np.sqrt(np.arange(len(X))+1.) # +1 to avoid divide by zero
    y = (irfft(X/S)).real[0:N]
    return normalise(y)
예제 #32
0
def rfft(data, n_samples, sampling_rate, fft_norm):
    """
    Calculate the FFT of a real-valued time-signal. The function returns only
    the right-hand side of the axis-symmetric spectrum. The normalization
    distinguishes between energy and power signals. Energy signals are not
    normalized in the forward transform. Power signals are normalized by their
    number of samples and to their effective value as well as compensated for
    the missing energy from the left-hand side of the spectrum. This ensures
    that the energy of the time signal and the right-hand side of the spectrum
    are equal and thus fulfill Parseval's theorem.

    Parameters
    ----------
    data : array, double
        Array containing the time domain signal with dimensions
        (..., n_samples)
    n_samples : int
        The number of samples
    sampling_rate : number
        sampling rate in Hz
    fft_norm : 'unitary', 'amplitude', 'rms', 'power', 'psd'
        See documentation of :py:func:`~pyfar.dsp.fft.normalization`.

    Returns
    -------
    spec : array, complex
        The complex valued right-hand side of the spectrum with dimensions
        (..., n_bins)

    """

    # DFT
    spec = fft_lib.rfft(data, n=n_samples, axis=-1)
    # Normalization
    spec = normalization(spec, n_samples, sampling_rate, fft_norm,
                         inverse=False, single_sided=True)

    return spec
예제 #33
0
def filtering(proj,geo,angles,parker):

	if parker:
		proj = parkerweight(proj.transpose(0,2,1),geo,angles,parker).transpose(0,2,1)
		# proj=parkerweight(proj,geo,angles,parker)

	filt_len = max(64,2 ** nextpow2(2 * geo.nDetector[0]))
	ramp_kernel = ramp_flat(filt_len)

	d = 1
	filt = filter(geo.filter,ramp_kernel[0],filt_len,d)

	filt = np.kron(np.ones((geo.nDetector[1],1)),filt).transpose()    

	for i in range(len(angles)):

        # Zero-padding:
		fproj = np.zeros((filt_len,geo.nDetector[1]),dtype=np.float32)
		fproj[int(filt_len / 2 - geo.nDetector[0] / 2):int(filt_len / 2 + geo.nDetector[0] / 2),:] = proj[:,:,i]   

		# Fourier-transform:
		n_byte_align(fproj, simd_alignment) 
		fproj = rfft(fproj, axis=0, threads=2)

		# Filter:
		fproj = fproj * filt[0:fproj.shape[0],:]

        # Inverse-Fourier:
		n_byte_align(fproj, simd_alignment) 
		fproj = np.real(irfft(fproj, axis=0, threads=2))
		end = len(fproj)

		# Crop:
		fproj = fproj[int(end / 2 - geo.nDetector[0] / 2):int(end / 2 + geo.nDetector[0] / 2),:] / 2 / geo.dDetector[0] * \
				 (2 * np.pi / len(angles)) / 2 * (geo.DSD / geo.DSO)
		proj[:,:,i] = fproj.astype(np.float32)

	return proj
예제 #34
0
def pink(N: int) -> np.ndarray:
    """
    Pink noise.

    * N: Amount of samples.

    Pink noise has equal power in bands that are proportionally wide.
    Power density decreases with 3 dB per octave.

    https://github.com/python-acoustics
    """

    # This method uses the filter with the following coefficients.
    # b = np.array([0.049922035, -0.095993537, 0.050612699, -0.004408786])
    # a = np.array([1, -2.494956002, 2.017265875, -0.522189400])
    # return lfilter(B, A, np.random.randn(N))

    # Another way would be using the FFT
    x = white(N)
    X = rfft(x) / N
    S = np.sqrt(np.arange(X.size) + 1.0)  # +1 to avoid divide by zero
    y = irfft(X / S).real[:N]

    return normalise(y)  # extremely tiny value 1e-9 without normalization
예제 #35
0
    def AF_MUSIC(self,
                 focusing_freq=-1,
                 npoints=1000,
                 signals=1,
                 shw=True,
                 block_run=True,
                 chunks=10):
        """Display a polar plot of estimated DOA using the MUSIC algorithm

        Arguments:
            focusing_freq (float): The frequency (in Hz) at which to perform the calculation. If <0, will default to 0.9*(spatial Nyquist frequency)
            npoints (int): The total number of points around the circle at which to evaluate.
            signals (int): The numbers of signals to locate.
            shw (bool): Show the plot? If False, will return the data that was to be plotted.
            block_run (bool): Pause execution of the file while the figure is open? Set to True for running in the command-line.
            chunks (int): How many sections to split the data up into. Will split up the data and average the result over the split sections
        """
        omegas = np.linspace(0, 2 * np.pi, npoints, endpoint=False)
        rest = np.zeros_like(omegas)

        if focusing_freq < 0:
            focusing_freq = self.spatial_nyquist_freq * 0.9

        # First generate Rxxs to get to T_autos
        # Tauto will go in here
        Tauto = np.zeros((self.mics.shape[0], self.mics.shape[0],
                          self.data.shape[0] // 2 + 1),
                         dtype="complex128")
        # Rxx will go in here
        Rxx = np.zeros((self.mics.shape[0], self.mics.shape[0],
                        self.data.shape[0] // 2 + 1),
                       dtype="complex128")
        # Ufi will go in here
        Ufi = np.zeros((self.mics.shape[0], self.mics.shape[0],
                        self.data.shape[0] // 2 + 1),
                       dtype="complex128")
        # Ryy will go in here
        Ryy = np.zeros((self.mics.shape[0], self.mics.shape[0],
                        self.data.shape[0] // 2 + 1),
                       dtype="complex128")

        # Split the data up into "chunks" sections
        indices = [
            int(x) for x in np.linspace(
                0, self.data.shape[0], num=chunks + 1, endpoint=True)
        ]

        # Calculate Rxx
        for mark in np.arange(len(indices) - 1):
            dcr = self.data[indices[mark]:indices[mark + 1], :]
            for chnl in np.arange(dcr.shape[1]):
                dcr[:, chnl] *= np.blackman(dcr.shape[0])

            # dft is RFFT of current data chunk
            dft = fft_pack.rfft(dcr, axis=0, n=self.data.shape[0]).T
            dft.shape = (dft.shape[0], 1, dft.shape[1])
            # print(dft.shape, self.data.shape, Tauto.shape)

            Rxx += np.einsum("jin,iln->jln", dft,
                             np.conj(np.transpose(dft, (1, 0, 2)))) / chunks

        # The frequencies for Tauto and DFT. They all have the same length so this is fine to do outside the loop
        pos = fft_pack.rfftfreq(self.data.shape[0]) * self.sample_rate

        # focusing_freq_index is the index along dft and Tauto to find f_0
        focusing_freq_index = np.argmin(np.abs(pos - focusing_freq))

        eig_f0, v_f0 = np.linalg.eigh(Rxx[:, :, focusing_freq_index])
        Uf0 = v_f0[:, np.argsort(np.abs(eig_f0))[::-1]]

        # Calculate Tautos
        for indx, fi in enumerate(pos):
            eig_fi, v_fi = np.linalg.eigh(Rxx[:, :, indx])
            Ufi[:, :, indx] = v_fi[:, np.argsort(np.abs(eig_fi))[::-1]]
            Tauto[:, :, indx] = dot(Uf0, np.conj(Ufi[:, :, indx].T)) / np.sqrt(
                pos.shape[0])

        # Calculate Ryy
        chunks = 1.0
        indices = [
            int(x) for x in np.linspace(
                0, self.data.shape[0], num=chunks + 1, endpoint=True)
        ]
        for mark in np.arange(len(indices) - 1):
            dcr = self.data[indices[mark]:indices[mark + 1], :]
            for chnl in np.arange(dcr.shape[1]):
                dcr[:, chnl] *= np.blackman(dcr.shape[0])

            # dft is RFFT of current data chunk
            dft = fft_pack.rfft(dcr, axis=0, n=self.data.shape[0]).T
            dft.shape = (dft.shape[0], 1, dft.shape[1])
            # print(dft.shape, self.data.shape, Tauto.shape)

            Yi = np.einsum("abc,bdc->adc", Tauto, dft)
            Ryy += np.einsum("jin,iln->jln", Yi,
                             np.conj(np.transpose(Yi, (1, 0, 2)))) / chunks

        Rcoh = np.sum(Ryy, axis=-1) / (self.data.shape[0] // 2 + 1)

        rest, _ = self._MUSIC1D_((focusing_freq, focusing_freq_index),
                                 omegas,
                                 SI=Rcoh)

        if shw:
            plt.figure()
            ax = plt.subplot(111, projection='polar')
            ax.plot(omegas, rest)
            ax.set_title("Estimated Acoustic Source Direction")
            plt.show(block=block_run)
        else:
            return rest
예제 #36
0
def fold(fh, comm, samplerate, fedge, fedge_at_top, nchan,
         nt, ntint, ngate, ntbin, ntw, dm, fref, phasepol,
         dedisperse='incoherent',
         do_waterfall=True, do_foldspec=True, verbose=True,
         progress_interval=100, rfi_filter_raw=None, rfi_filter_power=None,
         return_fits=False):
    """
    FFT data, fold by phase/time and make a waterfall series

    Folding is done from the position the file is currently in

    Parameters
    ----------
    fh : file handle
        handle to file holding voltage timeseries
    comm: MPI communicator or None
        will use size, rank attributes
    samplerate : Quantity
        rate at which samples were originally taken and thus double the
        band width (frequency units)
    fedge : float
        edge of the frequency band (frequency units)
    fedge_at_top: bool
        whether edge is at top (True) or bottom (False)
    nchan : int
        number of frequency channels for FFT
    nt, ntint : int
        total number nt of sets, each containing ntint samples in each file
        hence, total # of samples is nt*ntint, with each sample containing
        a single polarisation
    ngate, ntbin : int
        number of phase and time bins to use for folded spectrum
        ntbin should be an integer fraction of nt
    ntw : int
        number of time samples to combine for waterfall (does not have to be
        integer fraction of nt)
    dm : float
        dispersion measure of pulsar, used to correct for ism delay
        (column number density)
    fref: float
        reference frequency for dispersion measure
    phasepol : callable
        function that returns the pulsar phase for time in seconds relative to
        start of the file that is read.
    dedisperse : None or string (default: incoherent).
        None, 'incoherent', 'coherent', 'by-channel'.
        Note: None really does nothing
    do_waterfall, do_foldspec : bool
        whether to construct waterfall, folded spectrum (default: True)
    verbose : bool or int
        whether to give some progress information (default: True)
    progress_interval : int
        Ping every progress_interval sets
    return_fits : bool (default: False)
        return a subint fits table for rank == 0 (None otherwise)

    """
    assert dedisperse in (None, 'incoherent', 'by-channel', 'coherent')
    need_fine_channels = dedisperse in ['by-channel', 'coherent']
    assert nchan % fh.nchan == 0
    if dedisperse in ['incoherent', 'by-channel'] and fh.nchan > 1:
        oversample = nchan // fh.nchan
        assert ntint % oversample == 0
    else:
        oversample = 1

    if dedisperse == 'coherent' and fh.nchan > 1:
        raise ValueError("Cannot coherently dedisperse channelized data.")

    if comm is None:
        mpi_rank = 0
        mpi_size = 1
    else:
        mpi_rank = comm.rank
        mpi_size = comm.size

    npol = getattr(fh, 'npol', 1)
    assert npol == 1 or npol == 2
    if verbose > 1 and mpi_rank == 0:
        print("Number of polarisations={}".format(npol))

    # initialize folded spectrum and waterfall
    # TODO: use estimated number of points to set dtype
    if do_foldspec:
        foldspec = np.zeros((ntbin, nchan, ngate, npol**2), dtype=np.float32)
        icount = np.zeros((ntbin, nchan, ngate), dtype=np.int32)
    else:
        foldspec = None
        icount = None

    if do_waterfall:
        nwsize = nt*ntint//ntw//oversample
        waterfall = np.zeros((nwsize, nchan, npol**2), dtype=np.float64)
    else:
        waterfall = None

    if verbose and mpi_rank == 0:
        print('Reading from {}'.format(fh))

    nskip = fh.tell()/fh.blocksize
    if nskip > 0:
        if verbose and mpi_rank == 0:
            print('Starting {0} blocks = {1} bytes out from start.'
                  .format(nskip, nskip*fh.blocksize))

    dt1 = (1./samplerate).to(u.s)
    # need 2*nchan real-valued samples for each FFT
    if fh.telescope == 'lofar':
        dtsample = fh.dtsample
    else:
        dtsample = nchan // oversample * 2 * dt1
    tstart = dtsample * ntint * nskip

    # pre-calculate time delay due to dispersion in coarse channels
    # for channelized data, frequencies are known

    tb = -1. if fedge_at_top else +1.
    if fh.nchan == 1:
        if getattr(fh, 'data_is_complex', False):
            # for complex data, really each complex sample consists of
            # 2 real ones, so multiply dt1 by 2.
            freq = fedge + tb * fftfreq(nchan, 2.*dt1)
            if dedisperse == 'coherent':
                fcoh = fedge + tb * fftfreq(nchan*ntint, 2.*dt1)
                fcoh.shape = (-1, 1)
            elif dedisperse == 'by-channel':
                fcoh = freq + tb * fftfreq(ntint, dtsample)[:, np.newaxis]
        else:  # real data
            freq = fedge + tb * rfftfreq(nchan*2, dt1)
            if dedisperse == 'coherent':
                fcoh = fedge + tb * rfftfreq(ntint*nchan*2, dt1)
                fcoh.shape = (-1, 1)
            elif dedisperse == 'by-channel':
                fcoh = freq + tb * fftfreq(ntint, dtsample)[:, np.newaxis]
        freq_in = freq

    else:
        # Input frequencies may not be the ones going out.
        freq_in = fh.frequencies
        if oversample == 1:
            freq = freq_in
        else:
            freq = freq_in[:, np.newaxis] + tb * fftfreq(oversample, dtsample)

        fcoh = freq_in + tb * fftfreq(ntint, dtsample)[:, np.newaxis]

    # print('fedge_at_top={0}, tb={1}'.format(fedge_at_top, tb))
    # By taking only up to nchan, we remove the top channel at the Nyquist
    # frequency for real, unchannelized data.
    ifreq = freq[:nchan].ravel().argsort()

    # pre-calculate time offsets in (input) channelized streams
    dt = dispersion_delay_constant * dm * (1./freq_in**2 - 1./fref**2)

    if need_fine_channels:
        # pre-calculate required turns due to dispersion.
        #
        # set frequency relative to which dispersion is coherently corrected
        if dedisperse == 'coherent':
            _fref = fref
        else:
            _fref = freq_in[np.newaxis, :]
        # (check via eq. 5.21 and following in
        # Lorimer & Kramer, Handbook of Pulsar Astronomy
        dang = (dispersion_delay_constant * dm * fcoh *
                (1./_fref-1./fcoh)**2) * u.cycle
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            dd_coh = np.exp(dang * 1j).conj().astype(np.complex64)

        # add dimension for polarisation
        dd_coh = dd_coh[..., np.newaxis]

    # Calculate the part of the whole file this node should handle.
    size_per_node = (nt-1)//mpi_size + 1
    start_block = mpi_rank*size_per_node
    end_block = min((mpi_rank+1)*size_per_node, nt)
    for j in range(start_block, end_block):
        if verbose and j % progress_interval == 0:
            print('#{:4d}/{:4d} is doing {:6d}/{:6d} [={:6d}/{:6d}]; '
                  'time={:18.12f}'
                  .format(mpi_rank, mpi_size, j+1, nt,
                          j-start_block+1, end_block-start_block,
                          (tstart+dtsample*j*ntint).value))  # time since start

        # Just in case numbers were set wrong -- break if file ends;
        # better keep at least the work done.
        try:
            raw = fh.seek_record_read(int((nskip+j)*fh.blocksize),
                                      fh.blocksize)
        except(EOFError, IOError) as exc:
            print("Hit {0!r}; writing data collected.".format(exc))
            break
        if verbose >= 2:
            print("#{:4d}/{:4d} read {} items"
                  .format(mpi_rank, mpi_size, raw.size), end="")

        if npol == 2 and raw.dtype.fields is not None:
            raw = raw.view(raw.dtype.fields.values()[0][0])

        if fh.nchan == 1:  # raw.shape=(ntint*npol)
            raw = raw.reshape(-1, npol)
        else:              # raw.shape=(ntint, nchan*npol)
            raw = raw.reshape(-1, fh.nchan, npol)

        if dedisperse == 'incoherent' and oversample > 1:
            raw = ifft(raw, axis=1, **_fftargs).reshape(-1, nchan, npol)
            raw = fft(raw, axis=1, **_fftargs)

        if rfi_filter_raw is not None:
            raw, ok = rfi_filter_raw(raw)
            if verbose >= 2:
                print("... raw RFI (zap {0}/{1})"
                      .format(np.count_nonzero(~ok), ok.size), end="")

        if np.can_cast(raw.dtype, np.float32):
            vals = raw.astype(np.float32)
        else:
            assert raw.dtype.kind == 'c'
            vals = raw

        # For pre-channelized data, data are always complex,
        # and should have shape (ntint, nchan, npol).
        # For baseband data, we wish to get to the same shape for
        # incoherent or by_channel, or just to fully channelized for coherent.
        if fh.nchan == 1:
            # If we need coherent dedispersion, do FT of whole thing,
            # otherwise to output channels, mimicking pre-channelized data.
            if raw.dtype.kind == 'c':  # complex data
                nsamp = len(vals) if dedisperse == 'coherent' else nchan
                vals = fft(vals.reshape(-1, nsamp, npol), axis=1,
                           **_fftargs)
            else:  # real data
                nsamp = len(vals) if dedisperse == 'coherent' else nchan * 2
                vals = rfft(vals.reshape(-1, nsamp, npol), axis=1,
                            **_rfftargs)
                # Sadly, the way data are stored depends on what FFT routine
                # one is using.  We cannot deal with scipy's.
                if vals.dtype.kind == 'f':
                    raise TypeError("Can no longer deal with scipy's format "
                                    "for storing FTs of real data.")

        if fedge_at_top:
            # take complex conjugate to ensure by-channel de-dispersion is
            # applied correctly.
            # This needs to be done for ARO data, since we are in 2nd Nyquist
            # zone; not clear it is needed for other telescopes.
            np.conj(vals, out=vals)

        # Now we coherently dedisperse, either all of it or by channel.
        if need_fine_channels:
            # for by_channel, we have vals.shape=(ntint, nchan, npol),
            # and want to FT over ntint to get fine channels;
            if vals.shape[0] > 1:
                fine = fft(vals, axis=0, **_fftargs)
            else:
                # for coherent, we just reshape:
                # (1, ntint*nchan, npol) -> (ntint*nchan, 1, npol)
                fine = vals.reshape(-1, 1, npol)

            # Dedisperse.
            fine *= dd_coh

            # Still have fine.shape=(ntint, nchan, npol),
            # w/ nchan=1 for coherent.
            if fine.shape[1] > 1 or raw.dtype.kind == 'c':
                vals = ifft(fine, axis=0, **_fftargs)
            else:
                vals = irfft(fine, axis=0, **_rfftargs)

            if fine.shape[1] == 1 and nchan > 1:
                # final FT to get requested channels
                if vals.dtype.kind == 'f':
                    vals = vals.reshape(-1, nchan*2, npol)
                    vals = rfft(vals, axis=1, **_rfftargs)
                else:
                    vals = vals.reshape(-1, nchan, npol)
                    vals = fft(vals, axis=1, **_fftargs)
            elif dedisperse == 'by-channel' and oversample > 1:
                vals = vals.reshape(-1, oversample, fh.nchan, npol)
                vals = fft(vals, axis=1, **_fftargs)
                vals = vals.transpose(0, 2, 1, 3).reshape(-1, nchan, npol)

            # vals[time, chan, pol]
            if verbose >= 2:
                print("... dedispersed", end="")

        if npol == 1:
            power = vals.real**2 + vals.imag**2
        else:
            p0 = vals[..., 0]
            p1 = vals[..., 1]
            power = np.empty(vals.shape[:-1] + (4,), np.float32)
            power[..., 0] = p0.real**2 + p0.imag**2
            power[..., 1] = p0.real*p1.real + p0.imag*p1.imag
            power[..., 2] = p0.imag*p1.real - p0.real*p1.imag
            power[..., 3] = p1.real**2 + p1.imag**2

        if verbose >= 2:
            print("... power", end="")

        # current sample positions and corresponding time in stream
        isr = j*(ntint // oversample) + np.arange(ntint // oversample)
        tsr = (isr*dtsample*oversample)[:, np.newaxis]

        if rfi_filter_power is not None:
            power = rfi_filter_power(power, tsr.squeeze())
            print("... power RFI", end="")

        # correct for delay if needed
        if dedisperse in ['incoherent', 'by-channel']:
            # tsample.shape=(ntint/oversample, nchan_in)
            tsr = tsr - dt

        if do_waterfall:
            # # loop over corresponding positions in waterfall
            # for iw in xrange(isr[0]//ntw, isr[-1]//ntw + 1):
            #     if iw < nwsize:  # add sum of corresponding samples
            #         waterfall[iw, :] += np.sum(power[isr//ntw == iw],
            #                                    axis=0)[ifreq]
            iw = np.round((tsr / dtsample / oversample).to(1)
                          .value / ntw).astype(int)
            for k, kfreq in enumerate(ifreq):  # sort in frequency while at it
                iwk = iw[:, (0 if iw.shape[1] == 1 else kfreq // oversample)]
                iwk = np.clip(iwk, 0, nwsize-1, out=iwk)
                iwkmin = iwk.min()
                iwkmax = iwk.max()+1
                for ipow in range(npol**2):
                    waterfall[iwkmin:iwkmax, k, ipow] += np.bincount(
                        iwk-iwkmin, power[:, kfreq, ipow], iwkmax-iwkmin)
            if verbose >= 2:
                print("... waterfall", end="")

        if do_foldspec:
            ibin = (j*ntbin) // nt  # bin in the time series: 0..ntbin-1

            # times and cycles since start time of observation.
            tsample = tstart + tsr
            phase = (phasepol(tsample.to(u.s).value.ravel())
                     .reshape(tsample.shape))
            # corresponding PSR phases
            iphase = np.remainder(phase*ngate, ngate).astype(np.int)

            for k, kfreq in enumerate(ifreq):  # sort in frequency while at it
                iph = iphase[:, (0 if iphase.shape[1] == 1
                                 else kfreq // oversample)]
                # sum and count samples by phase bin
                for ipow in range(npol**2):
                    foldspec[ibin, k, :, ipow] += np.bincount(
                        iph, power[:, kfreq, ipow], ngate)
                icount[ibin, k, :] += np.bincount(
                    iph, power[:, kfreq, 0] != 0., ngate).astype(np.int32)

            if verbose >= 2:
                print("... folded", end="")

        if verbose >= 2:
            print("... done")

    #Commented out as workaround, this was causing "Referenced before assignment" errors with JB data
    #if verbose >= 2 or verbose and mpi_rank == 0:
    #    print('#{:4d}/{:4d} read {:6d} out of {:6d}'
    #          .format(mpi_rank, mpi_size, j+1, nt))

    if npol == 1:
        if do_foldspec:
            foldspec = foldspec.reshape(foldspec.shape[:-1])
        if do_waterfall:
            waterfall = waterfall.reshape(waterfall.shape[:-1])

    return foldspec, icount, waterfall
예제 #37
0
=======
        if fh.telescope in ('arochime','arochime-raw'):
            # take complex conjugate to ensure by-channel de-dispersion is applied correctly
            vals = np.conj(vals)

>>>>>>> e6d25c1bfcc5a3426bc62becc3b3075fbea23ebc
        if fh.nchan == 1:
            # If we need coherent dedispersion, do FT of whole thing,
            # otherwise to output channels, mimicking pre-channelized data.
            if raw.dtype.kind == 'c':  # complex data
                nsamp = len(vals) if dedisperse == 'coherent' else nchan
                vals = fft(vals.reshape(-1, nsamp, npol), axis=1,
                           **_fftargs)
            else:  # real data
                nsamp = len(vals) if dedisperse == 'coherent' else nchan * 2
                vals = rfft(vals.reshape(-1, nsamp, npol), axis=1,
                            **_rfftargs)
                # Sadly, the way data are stored depends on what FFT routine
                # one is using.  We cannot deal with scipy's.
                if vals.dtype.kind == 'f':
                    raise TypeError("Can no longer deal with scipy's format "
                                    "for storing FTs of real data.")

        if fedge_at_top:
            # take complex conjugate to ensure by-channel de-dispersion is
            # applied correctly.
            # This needs to be done for ARO data, since we are in 2nd Nyquist
            # zone; not clear it is needed for other telescopes.
            np.conj(vals, out=vals)

        # Now we coherently dedisperse, either all of it or by channel.
        if need_fine_channels:
예제 #38
0
    def AF_MUSIC2D(self,
                   focusing_freq=-1,
                   signals=1,
                   xrange=(-50, 50),
                   yrange=(-50, 50),
                   xstep=False,
                   ystep=False,
                   colormap="gist_heat",
                   shw=True,
                   block_run=True,
                   no_fig=False,
                   chunks=10):
        """Displays a heatmap for visual inspection of AF-MUSIC-based location estimation.

        Generates a grid of provided dimension/resolution, and evaluates the AF-MUSIC algorithm at
        each point on the grid.

        Arguments:
            focusing_freq (float): The frequency (in Hz) at which to perform the calculation. If <0, will default to 0.9*(spatial Nyquist frequency)
            signals (int): The number of signals to locate.
            xrange (float, float): The lower and upper bound in the x-direction.
            yrange (float, float): The lower and upper bound in the y-direction.
            xstep (float): If given, determines the size of the steps in the x-direction. Otherwise defaults to 1000 steps.
            ystep (float): If given, determines the size of the steps in the y-direction. Otherwise defaults to 1000 steps.
            colormap (str): The colour map for the heatmap. See https://matplotlib.org/examples/color/colormaps_reference.html
            shw (bool): If False, return the axis object rather than display.
            block_run (bool): Pause execution of the file while the figure is open? Set to True for running in the command-line.
            no_fig (bool): If True, return the heatmap grid rather than plot it.

        Returns:
            np.array: Returns EITHER the current (filled) heatmap domain if no_fig == True, OR a handle to the displayed figure.
        """
        raise NotImplementedError

        self.dataFFT = fft_pack.rfft(self.data, axis=0).T
        self.numbins = self.dataFFT.shape[1]
        pos = fft_pack.rfftfreq(self.data.shape[0]) * self.sample_rate

        if focusing_freq < 0:
            focusing_freq = self.spatial_nyquist_freq * 0.45
            # focusing_freq = pos[np.argmax(self.dataFFT[0, :])]
        else:
            focusing_freq = 1000

        idxs = np.array(np.arange(pos.shape[0]))

        refidx = np.argmin(abs(pos - focusing_freq))
        Rcoh = np.zeros((self.dataFFT.shape[0], self.dataFFT.shape[0]),
                        dtype='complex128')
        ul, self.Uf0 = la.eigh(
            dot(self.dataFFT[:, refidx:refidx + 1],
                self.dataFFT[:, refidx:refidx + 1].conj().T) /
            self.dataFFT.shape[0])
        ul = ul.real
        self.Uf0 = self.Uf0[:, argsort(abs(ul))[::-1]]

        pool = Pool(processes=7)
        res = pool.map(self._UfitoRyy_, idxs)
        pool.close()
        for r in res:
            Rcoh += r

        if xstep and ystep:
            xdom = np.linspace(start=xrange[0],
                               stop=xrange[1],
                               num=int((xrange[1] - xrange[0]) // xstep))
            ydom = np.linspace(start=yrange[0],
                               stop=yrange[1],
                               num=int((yrange[1] - yrange[0]) // ystep))
        else:
            xdom = np.linspace(start=xrange[0], stop=xrange[1], num=1000)
            ydom = np.linspace(start=yrange[0], stop=yrange[1], num=1000)
        self._hm_domain_ = np.zeros((len(ydom), len(xdom)))

        xdom, ydom = np.meshgrid(xdom, ydom)
        self._hm_domain_ = self._MUSIC2D_((pos[refidx], refidx),
                                          xdom,
                                          ydom,
                                          numsignals=signals,
                                          SI=Rcoh)

        if no_fig:
            return self._hm_domain_

        f = plt.figure()
        plt.imshow(self._hm_domain_,
                   cmap=colormap,
                   interpolation='none',
                   origin='lower',
                   extent=[xrange[0], xrange[1], yrange[0], yrange[1]])
        plt.colorbar()
        plt.xlabel("Horiz. Dist. from Center of Array [m]")
        plt.ylabel("Vert. Dist. from Center of Array [m]")

        if shw:
            plt.show(block=block_run)
            return
        else:
            return f
예제 #39
0
파일: stft.py 프로젝트: SachsLab/pytf
def stft(x,
         binsize=1024,
         overlap_factor=.5,
         hopsize=None,
         window='hamming',
         **kwargs):
    """ STFT, Short-Term Fourier Transform.

    Parameters:
    -----------
    x: 2d-ndarray, (n_ch, n_samp)
        Multi-channel signal.

    binsize: int
        Window size for processing FFT on.

    overlap_factor: float
        The percentage of overlapping between consecutive windows.

    hopsize: int
        The sample size required to jump to the next row.

    window: str (default: 'hamming')
        The window used to create overlapping slices of the time domain signal.

    kwargs:
        The key-word arguments for rfft.

    Return:
    -------
    X: ndarray, (n_ch, n_win, binsize // 2)
    """
    # Sanity check
    if not np.isrealobj(x):
        raise ValueError("x is not a real valued array.")

    if x.ndim > 2:
        raise ValueError(
            "The dimension of the ndarray must be less than or equal to 2!")

    x = np.atleast_2d(x)
    n_ch, n_samp = x.shape

    if hopsize is not None:
        _overlap_factor = hopsize / binsize
        if overlap_factor != _overlap_factor:
            raise ValueError(
                "The 'overlap_factor' calculated from hopsize/binsize does not match the input."
            )

    if overlap_factor in [0, 1] and binsize != hopsize != n_samp:
        binsize = n_samp
        hopsize = 0 if overlap_factor else binsize
    else:
        hopsize = int(binsize *
                      (1 - overlap_factor)) if hopsize is None else hopsize

    if hopsize:
        n_win = n_samp / hopsize
        n_win = int(n_win + 1) if overlap_factor else int(n_win)
        length = hopsize
    else:
        n_win = 1
        length = binsize

    if overlap_factor in [0, 1]:
        _x = np.zeros((n_ch, n_win * length))
    else:
        _x = np.zeros((n_ch, (n_win + 1) * length))

    _x[:, binsize // 2:binsize // 2 + n_samp] = x

    # Process
    win_ = get_window(window, binsize)
    frames = stride_tricks.as_strided(_x,
                                      shape=(n_ch, n_win, binsize),
                                      strides=(_x.strides[0],
                                               _x.strides[1] * hopsize,
                                               _x.strides[1]))
    X = fft.rfft(frames * win_, **kwargs)

    return X
예제 #40
0
def toFrequencyResponse(data):
    dat = rfft(data, planner_effort="FFTW_ESTIMATE")
    return 20 * numpy.log10(numpy.abs(dat))