Exemplo n.º 1
0
        def _from_timeseries(ts):
            """Generate a `Spectrogram` from a `TimeSeries`.
            """
            # calculate specgram parameters
            dt = stride
            df = 1 / fftlength

            # get size of spectrogram
            nsteps_ = int(ts.size // nsamp)
            nfreqs = int(fftlength * ts.sample_rate.value // 2 + 1)

            # generate output spectrogram
            unit = scale_timeseries_units(
                ts.unit, kwargs.get('scaling', 'density'))
            out = Spectrogram(numpy.zeros((nsteps_, nfreqs)), unit=unit,
                              channel=ts.channel, epoch=ts.epoch, f0=0, df=df,
                              dt=dt, copy=True)

            if not nsteps_:
                return out

            # stride through TimeSeries, calcaulting PSDs
            for step in range(nsteps_):
                # find step TimeSeries
                idx = nsamp * step
                idx_end = idx + nsamp
                stepseries = ts[idx:idx_end]
                steppsd = stepseries.psd(fftlength=fftlength, overlap=overlap,
                                         method=method, **kwargs)
                out.value[step, :] = steppsd.value

            return out
Exemplo n.º 2
0
def psdgram(timeseries, stride):
    """
    calculates one-sided PSD from timeseries
    properly using welch's method by averaging adjacent non-ovlping
    segments. Since default fftgram overlaps segments
    we have to be careful here...
    Parameters
    ----------
        fftgram : Spectrogram object
            complex fftgram
        adjacent : `int`
            number of adjacent segments
            to calculate PSD of middle segment
    Returns
    -------
        psdgram : Spectrogram object
            psd spectrogram calculated in
            spirit of STAMP/stochastic
    """
    fftlength = stride
    dt = stride
    df = 1. / fftlength
    # number of values in a step
    stride *= timeseries.sample_rate.value
    # number of steps
    nsteps = 2 * int(timeseries.size // stride) - 1
    # only get positive frequencies
    nfreqs = int(fftlength * timeseries.sample_rate.value) / 2.
    # initialize the spectrogram
    if timeseries.unit:
        unit = timeseries.unit / u.Hz
    else:
        unit = 1 / u.Hz
    out = Spectrogram(np.zeros((nsteps, int(nfreqs))),
                      name=timeseries.name, epoch=timeseries.epoch,
                      f0=df / 2, df=df, dt=dt, copy=True,
                      unit=unit)
    # stride through TimeSeries, recording FFTs as columns of Spectrogram
    for step in range(nsteps):
        # indexes for this step
        idx = (stride / 2) * step
        idx_end = idx + stride
        stepseries = timeseries[idx:idx_end]
        steppsd = stepseries.psd()[1:]
        out.value[step, :] = steppsd.value

    psdleft = np.hstack((out.T, np.zeros((out.shape[1], 4))))
    psdright = np.hstack((np.zeros((out.shape[1], 4)), out.T))
    psd_temp = ((psdleft + psdright) / 2).T
    # create spectrogram object. multiply by 2 for one-sided.
    psd = Spectrogram(2 * psd_temp.value[4:-4],
                      name=timeseries.name, epoch=timeseries.epoch.value +
                      2 * dt,
                      f0=df, df=df, dt=dt, copy=True,
                      unit=unit)
    return psd
Exemplo n.º 3
0
def stamp_snr(channel1, channel2, stride):
    """
    calculates stamp snr
    Parameters
    ----------
        channel1 : TimeSeries
            channel1 timeseries
        channel2 : TimeSeries
            channel2 TimeSeries

    Returns
    -------
        snr : Spectrogram
            stamp snr spectrogram
    """
    y = stamp_y(channel1, channel2, stride)
    variance = stamp_variance(channel1, channel2, stride)
    snr = Spectrogram(y.value / variance.value**0.5,
                      unit=None,
                      dt=y.dt,
                      f0=y.f0,
                      df=y.df,
                      epoch=y.epoch,
                      copy=True)
    return snr
Exemplo n.º 4
0
def _save_longterm_spectrogram(axis, idnum, fname, **kwargs):
    '''
    '''
    prefix = kwargs.pop('prefix', './data')
    specgrams = Spectrogram.read(fname[0], format='hdf5')
    for fname in fname[1:]:
        try:
            specgrams.append(Spectrogram.read(fname, format='hdf5'),
                             gap='ignore')
        except:
            log.debug(traceback.format_exc())
            raise ValueError('AAAA')
    fname_hdf5 = prefix + '/SG_LongTerm_{0}_{1}.hdf5'.format(axis, idnum)
    log.debug('{0} Combined'.format(fname_hdf5))
    specgrams.write(fname_hdf5, format='hdf5', overwrite=True)
    log.debug('{0} Saved'.format(fname_hdf5))
Exemplo n.º 5
0
def get_specgram(*chname,**kwargs):
    n = len(chname)
    if n==2:
        chname1,chname2 = chname
        specgram = get_csd_specgram(chname1,chname2,**kwargs)
        return specgram
    elif n==1:
        chname = chname[0]
    else:
        raise ValueError('Wrong chname arguments')
    

    fftlength = kwargs.pop('fftlength',None)
    remake = kwargs.pop('remake',False)
    overlap = kwargs.pop('overlap',None)
    hdf5fname = to_hdf5fname(chname,**kwargs)
    #print hdf5fname
    if remake:
        if os.path.exists(hdf5fname):
            os.remove(hdf5fname)
        timeseries = get_timeseries(chname,**kwargs)
        specgram = timeseries.spectrogram(stride=fftlength*2,
                                          fftlength=fftlength,
                                          overlap=overlap,
                                          window='hanning')
        #exit()        
        specgram.write(hdf5fname)
        return specgram
    else:
        #warnings.warn('Dont use fftlength option..')
        specgram = Spectrogram.read(hdf5fname)
        return specgram
Exemplo n.º 6
0
def plot_spectrogram_from_ts(ts):
    plot = SpectrogramPlot()
    ax = plot.gca()
    ax.plot(Spectrogram(spec))
    #pyplot.ylim(1e-9, 1e-2)
    #pyplot.xlim(0.1, 500)
    #pyplot.loglog()
    pyplot.savefig("specgram.png", dpi=300)
    pyplot.close()
Exemplo n.º 7
0
    def fftgram(self, stride):
        """Calculate the Fourier-gram of this `TimeSeries`.

        At every ``stride``, a single, complex FFT is calculated.

        Parameters
        ----------
        stride : `float`
            number of seconds in single PSD (column of spectrogram)

        Returns
        -------
        fftgram : :class:`~gwpy.spectrogram.core.Spectrogram`
            a Fourier-gram
        """
        from ..spectrogram import Spectrogram

        fftlength = stride
        dt = stride
        df = 1/fftlength
        stride *= self.sample_rate.value
        # get size of Spectrogram
        nsteps = int(self.size // stride)
        # get number of frequencies
        nfreqs = int(fftlength*self.sample_rate.value)

        # generate output spectrogram
        dtype = numpy.complex
        out = Spectrogram(numpy.zeros((nsteps, nfreqs), dtype=dtype),
                          name=self.name, epoch=self.epoch, f0=0, df=df,
                          dt=dt, copy=True, unit=self.unit, dtype=dtype)
        # stride through TimeSeries, recording FFTs as columns of Spectrogram
        for step in range(nsteps):
            # find step TimeSeries
            idx = stride * step
            idx_end = idx + stride
            stepseries = self[idx:idx_end]
            # calculated FFT and stack
            stepfft = stepseries.fft()
            out[step] = stepfft.value
            if step == 0:
                out.frequencies = stepfft.frequencies
        return out
Exemplo n.º 8
0
def csdgram(channel1, channel2, stride, overlap=None, pad=False):
    """
    calculates one-sided csd spectrogram between two timeseries
    or fftgrams. Allows for flexibility for holding DARM
    fftgram in memory while looping over others.

    Parameters
    ----------
    channel1 : TimeSeries or Spectrogram object
        timeseries from channel 1
    timeseries2 : TimeSeries or Spectrogram object
        timeseries from channel 2

    Returns
    -------
    csdgram : spectrogram object
        csd spectrogram for two objects
    """
    if isinstance(channel1, TimeSeries):
        fftgram1 = fftgram(channel1, stride, pad=pad, overlap=overlap)
    elif isinstance(channel1, Spectrogram):
        fftgram1 = channel1
    else:
        raise TypeError('First arg is either TimeSeries or Spectrogram object')
    if isinstance(channel2, TimeSeries):
        fftgram2 = fftgram(channel2, stride, pad=pad, overlap=overlap)
    elif isinstance(channel2, Spectrogram):
        fftgram2 = channel2
    else:
        raise TypeError('First arg is either TimeSeries or Spectrogram object')

    # clip off first 2 and last 2 segments to be consistent with psd
    # calculation
    out = np.conj(fftgram1.value) * fftgram2.value

    if pad:
        # if zero padded, take every other frequency
        out = out[:, 0::2]
        df = fftgram1.df * 2
        f0 = fftgram1.f0 * 2
    else:
        df = fftgram1.df
        f0 = fftgram1.f0

    csdname = 'csd'
    out = Spectrogram(out,
                      name=csdname,
                      epoch=fftgram1.epoch.value,
                      df=df,
                      dt=fftgram1.dt,
                      copy=True,
                      unit=fftgram1.unit * fftgram2.unit,
                      f0=f0)

    return out
Exemplo n.º 9
0
def get_array2d(start,end,axis='X',prefix='./data',**kwargs):
    '''
    '''
    nproc = kwargs.pop('nproc',4)
    bandpass = kwargs.pop('bandpass',None)
    blrms = kwargs.pop('blrms',None)
    fftlen = kwargs.pop('fftlen',2**8)
    overlap = fftlen/2

    # check existance of the spectrogram data
    fname_hdf5 = fname_hdf5_asd(start,end,prefix,axis)
    if os.path.exists(fname_hdf5):
        specgram = Spectrogram.read(fname_hdf5)
        if blrms:
            timeseries = specgram.crop_frequencies(blrms[0],blrms[1]).sum(axis=1)
            return timeseries
        return specgram
    
    # If spectrogram dose not exist, calculate it from timeseries data.
    try:
        fname = fname_gwf(start,end,prefix='./data')
        chname = get_seis_chname(start,end,axis=axis)
        # check existance of the timeseries data
        if os.path.exists(fname):
            data = TimeSeries.read(fname,chname,nproc=nproc)
        else:
            # when timeseries data dose not exist
            fnamelist = existedfilelist(start,end)
            chname = get_seis_chname(start,end)
            datadict = TimeSeriesDict.read(fnamelist,chname,nproc=nproc)
            datadict = datadict.resample(32)
            datadict = datadict.crop(start,end)
            chname = get_seis_chname(start,end,axis=axis)
            datadict.write(fname,format='gwf.lalframe')
            data = TimeSeries.read(fname,chname,nproc=nproc)
            # If data broken, raise Error.
            if data.value.shape[0] != 131072:
                log.debug(data.value.shape)
                log.debug('####### {0} {1}'.format(start,end))
                raise ValueError('data broken')
    except:
        log.debug(traceback.format_exc())
        raise ValueError('!!!')

    # if data broken, raise Error.
    if data.value.shape[0] != 131072: # (131072 = 2**17 = 2**12[sec] * 2**5[Hz] )
        log.debug(data.value.shape)
        log.debug('!!!!!!!! {0} {1}'.format(start,end))
        raise ValueError('data broken')

    # calculate from timeseries data
    specgram = data.spectrogram2(fftlength=fftlen,overlap=overlap,nproc=nproc)
    specgram.write(fname_hdf5,format='hdf5',overwrite=True)
    return specgram
Exemplo n.º 10
0
def plot_spectrogram_from_ts(ts, fname='specgram.png'):
    '''
    Plot spectrogram
    '''
    plot = SpectrogramPlot()
    ax = plot.gca()
    ax.plot(Spectrogram(spec))
    #plt.ylim(1e-9, 1e-2)
    #plt.xlim(0.1, 500)
    #plt.loglog()
    plt.savefig(fname, transparent=True)
    plt.close()
Exemplo n.º 11
0
def plot_spectrogram(spec, dt, df, ymax, t0, t1, fname="specgram.png"):
    '''
    Plot standard Fourier-based spectrogram
    '''
    plot = SpectrogramPlot()
    ax = plot.gca()
    ax.plot(Spectrogram(spec, dt=dt, df=df, epoch=float(t0)), cmap='viridis')
    plot.add_colorbar(label='Amplitude')
    plt.xlim(t0, t1)
    plt.ylim(0, ymax)
    plt.savefig(fname, transparent=True)  #,dpi=300)
    plt.close()
Exemplo n.º 12
0
def get_spectrogram(start, end, axis='X', seis='EXV', **kwargs):
    ''' Get Spectrogram    

    Parameters
    ----------
    start : `int`
        start GPS time.
    end : `int`
       end GPS time.

    Returns
    -------
    specgram : `gwpy.spectrogram.Spectrogram`
        spectrogram.
    '''
    nproc = kwargs.pop('nproc', 3)
    bandpass = kwargs.pop('bandpass', None)
    fftlen = kwargs.pop('fftlen', 2**8)
    diff = kwargs.pop('diff', False)
    fs = kwargs.pop('fs', 256)
    fname_hdf5 = fname_specgram(start, end, prefix=seis, axis=axis)

    # Load specgram from hdf5 file
    if os.path.exists(fname_hdf5):
        specgram = Spectrogram.read(fname_hdf5, format='hdf5')
        return specgram

    # If no file, make specgram from timeseries data
    try:
        chname = get_seis_chname(start, end, axis=axis, seis=seis)[0]
        fnamelist = existedfilelist(start, end)
        data = TimeSeries.read(fnamelist, chname, nproc=nproc)
        data = data.resample(fs)
        data = data.crop(start, end)
    except:
        log.debug(traceback.format_exc())
        raise ValueError('!!! {0} {1}'.format(start, end))

    # calculate specgram
    specgram = data.spectrogram2(fftlength=fftlen,
                                 overlap=fftlen / 2,
                                 nproc=nproc)
    try:
        fname_dir = '/'.join(fname_hdf5.split('/')[:4])
        if not os.path.exists(fname_dir):
            os.makedirs(fname_dir)
        specgram.write(fname_hdf5, format='hdf5', overwrite=True)
        log.debug('Make {0}'.format(fname_hdf5))
    except:
        log.debug(traceback.format_exc())
        raise ValueError('!!!')
    return specgram
Exemplo n.º 13
0
def save_asd(axis, available, percentile=50, **kwargs):
    prefix = kwargs.pop('prefix', './data')
    write = kwargs.pop('write', None)
    write_gwf = kwargs.pop('write_gwf', None)
    skip = kwargs.pop('skip', None)

    asd_fmt = '{0}/{1}_{2:02d}_LongTerm.hdf5'.format(prefix, axis, percentile)
    if os.path.exists(asd_fmt):
        #log.debug(asd_fmt+' Read')
        return FrequencySeries.read(asd_fmt, format='hdf5')

    log.debug(asd_fmt + ' Saving {0:02d} percentile'.format(percentile))
    fnamelist = [
        prefix + '/{0}_{1}_{2}.hdf5'.format(axis, start, end)
        for start, end in available
    ]
    specgrams = Spectrogram.read(fnamelist[0], format='hdf5')
    [specgrams.append(Spectrogram.read(fname,format='hdf5'),gap='ignore') \
     for fname in fnamelist]
    asd = specgrams.percentile(percentile)
    asd.write(asd_fmt, format='hdf5', overwrite=True)
    return asd
Exemplo n.º 14
0
def append_data(segment, **kwargs):
    '''
    '''
    blrms = kwargs.pop('blrms', False)
    n = len(segment)
    kwargs['n'] = len(segment)
    # i = 0
    start, end = segment[0]
    x = [get_spectrogram(start, end, axis='X', **kwargs).mean(axis=0)]
    y = [get_spectrogram(start, end, axis='Y', **kwargs).mean(axis=0)]
    z = [get_spectrogram(start, end, axis='Z', **kwargs).mean(axis=0)]
    # i > 1
    for i, (start, end) in enumerate(segment[1:]):
        x += [get_spectrogram(start, end, axis='X', **kwargs).mean(axis=0)]
        y += [get_spectrogram(start, end, axis='Y', **kwargs).mean(axis=0)]
        z += [get_spectrogram(start, end, axis='Z', **kwargs).mean(axis=0)]
        log.debug('{0:04d}/{1:04d} : Append {2} '.format(i + 2, n, start))

    # make spectrogram
    x = Spectrogram.from_spectra(*x)
    y = Spectrogram.from_spectra(*y)
    z = Spectrogram.from_spectra(*z)
    return x, y, z
Exemplo n.º 15
0
def create_matrix_from_file(coh_file, channels):
    """
    Creates coherence matrix from data that's in a file.
    Used typically as helper function for plotting

    Parameters
    ----------
    coh_file : str
        File containing coherence data
    channels : list (str)
        channels to plot

    Returns
    -------
    coh_matrix : Spectrogram object
        coherence matrix in form of spectrogram object
        returns automatically in terms of coherence SNRr -
        coherence * N.
        (not actually a spectrogram, though)
    frequencies : numpy array
        numpy array of frequencies associated with coherence matrix
    labels : list (str)
        labels for coherence matrix
    N : int
        Number of time segment used to create coherence spectra
    """
    labels = []
    counter = 0
    f = h5py.File(coh_file, 'r')
    # get number of averages
    N = f['info'].value
    channels = f['psd2s'].keys()
    failed_channels = f['failed_channels'].value
    print failed_channels
    First = 1
    for channel in channels:
        if First:
            # initialize matrix!
            darm_psd = FrequencySeries.from_hdf5(
                f['psd1'][f['psd1'].keys()[0]])
            First = 0
            coh_matrix = np.zeros((darm_psd.size, len(channels)))
        if channel in failed_channels:
            continue
        data = FrequencySeries.from_hdf5(f['coherences'][channel])
        labels.append(channel[3:-3].replace('_', '-'))
        coh_matrix[:data.size, counter] = data
        counter += 1
    coh_matrix = Spectrogram(coh_matrix * N)
    return coh_matrix, darm_psd.frequencies.value, labels, N
Exemplo n.º 16
0
def path_to_contour(tf_path, times, frequencies, t_unc=0, f_unc=0):
    """
    Convert a time-frequency path as a TimeSeries object to a Spectrogram.
    
    Parameters
    ----------
    tf_path : gwpy.TimeSeries object
        Time-frequency path.
    times : array
        Time bins of output spectrogram
    frequencies : array
        Frequency bins of output spectrogram
    t_unc : float, int, optional
        Time uncertainty; widens path contour by this amount in time.
    f_unc : float, int, optional
        Frequency uncertainty; widens path contour by this amount in frequency.
    
    Returns
    -------
    contour_path : gwpy.Spectrogram object
        Spectrogram whose values are 1 in pixels overlapping the time-frequency path and 0 elsewhere.
    """
    path_times = tf_path.times.value
    path_frequencies = tf_path.value
    values = np.zeros([times.size, frequencies.size])
    for i in range(times.size - 1):
        for j in range(frequencies.size - 1):
            t_idx = np.where((path_times >= times[i] - t_unc)
                             & (path_times < times[i + 1] + t_unc))[0]
            f_idx = np.where(
                (path_frequencies[t_idx] >= frequencies[j] - f_unc)
                & (path_frequencies[t_idx] < frequencies[j + 1] + f_unc))[0]
            if len(f_idx) > 0:
                values[i, j] = 1
    contour_path = Spectrogram(values, times=times, frequencies=frequencies)
    contour_path.name = tf_path.name
    return contour_path
Exemplo n.º 17
0
def plot_spectrogram(spec,
                     dt,
                     df,
                     sample_rate,
                     start_time,
                     end_time,
                     fname="specgram.png"):
    plot = SpectrogramPlot()
    ax = plot.gca()
    ax.plot(Spectrogram(spec, dt=dt, df=df, epoch=start_time), cmap='viridis')
    plot.add_colorbar(label='Amplitude')
    pyplot.xlim(start_time, end_time)
    pyplot.ylim(0, sample_rate / 2.)
    pyplot.savefig(fname)  #,dpi=300)
    pyplot.close()
Exemplo n.º 18
0
 def spectrogram(self):
     # check if times are continuous
     # check if freqs are continuous
     kwargs = {'name': 'magnetic data', 'channel': None, 'unit': units.nT}
     if self.cont_times:
         kwargs['t0'] = self.times[0]
         kwargs['dt'] = self.times[2] - self.times[1]
     else:
         kwargs['times'] = self.times
     if self.cont_freqs:
         kwargs['f0'] = self.frequencies[0]
         kwargs['df'] = self.frequencies[2] - self.frequencies[1]
     else:
         kwargs['frequencies'] = self.frequencies
     return Spectrogram(self['data']['spectra'].value.squeeze(), **kwargs)
Exemplo n.º 19
0
def _coherence_spectrogram(fftgram1,
                           fftgram2,
                           stride,
                           segmentDuration,
                           pad=False):
    max_f = min(fftgram1.shape[1], fftgram2.shape[1])
    csd12 = csdgram(fftgram1[:, 0:max_f],
                    fftgram2[:, 0:max_f],
                    stride,
                    pad=pad)
    if pad:
        psd1 = np.abs(fftgram1[:, 0::2])**2
        psd2 = np.abs(fftgram2[:, 0::2])**2
    else:
        psd1 = np.abs(fftgram1)**2
        psd2 = np.abs(fftgram2)**2

    # average over strides if necessary
    if not segmentDuration:
        segmentDuration = stride
    if segmentDuration < stride:
        raise ValueError('segmentDuration must be longer than or equal\
                         to stride')
    if segmentDuration % stride:
        raise ValueError('stride must evenly divide segmentDuration')

    navgs = segmentDuration / stride
    if not fftgram1.shape[0] % navgs:
        print 'WARNING: will cut off last segment because segmentDuration doesnt evenly divide total time window'
    nsegs = int(fftgram1.shape[0] / navgs)
    nfreqs = csd12.frequencies.size
    coh_spec = np.zeros((nsegs, nfreqs))
    for i in range(nsegs):
        idx1 = i * navgs
        idx2 = idx1 + navgs
        coh_spec[i, :] = np.abs(np.mean(csd12[idx1:idx2, :], 0) ** 2)\
            / ((np.mean(psd1[idx1:idx2, :nfreqs], 0)) *
                np.mean(psd2[idx1:idx2, :nfreqs], 0))
    coh_spec = Spectrogram(coh_spec,
                           df=csd12.df,
                           dt=segmentDuration,
                           epoch=csd12.epoch,
                           unit=None,
                           name='coherence spectrogram')
    return coh_spec
Exemplo n.º 20
0
def get_csd_specgram(chname1,chname2,remake=True,fftlength=2**6,overlap=0.0,**kwargs):
    hdf5fname = to_hdf5fname(chname1,chname2)
    if remake:
        if os.path.exists(hdf5fname):
            os.remove(hdf5fname)
        timeseries1 = get_timeseries(chname1,**kwargs)
        timeseries2 = get_timeseries(chname2,**kwargs)
        specgram = timeseries1.csd_spectrogram(timeseries2,
                                               stride=fftlength*2,
                                               fftlength=fftlength,
                                               overlap=overlap,
                                               window='hanning',
                                               nproc=2)
        specgram.write(hdf5fname)
        return specgram
    else:
        #warnings.warn('Dont use fftlength option..')
        specgram = Spectrogram.read(hdf5fname)
        return specgram
Exemplo n.º 21
0
    def fft_amp_spectrogram(self):
        # vals = self['data']['fftamp'].value.squeeze()
        # intermediate = vals['real'] + 1j * vals['imag']
        intermediate = self['data']['fftamp'].value.squeeze()['real'] +\
            1j * self['data']['fftamp'].value.squeeze()['imag']
        # intermediate = np.zeros((self.times.size, self.frequencies.size))

        # intermediate = np.zeros(vals.flatten().size)
        kwargs = {'name': 'magnetic data', 'channel': None, 'unit': units.nT}
        if self.cont_times:
            kwargs['t0'] = self.times[0]
            kwargs['dt'] = self.times[2] - self.times[1]
        else:
            kwargs['times'] = self.times
        if self.cont_freqs:
            kwargs['f0'] = self.frequencies[0]
            kwargs['df'] = self.frequencies[2] - self.frequencies[1]
        else:
            kwargs['frequencies'] = self.frequencies
        return Spectrogram(intermediate, **kwargs)
Exemplo n.º 22
0
 def cross_corr(self, other):
     if npt.assert_almost_equal(self.frequencies, other.frequencies):
         raise ValueError('frequencies must match')
     newmat = np.zeros((self.spectrogram.shape))
     this_specgram = self.fft_amp_spectrogram.copy()
     other_specgram = other.fft_amp_spectrogram.copy()
     final_times = []
     if self.cont_times and other.cont_times:
         et = int(
             min(this_specgram.times[-1].value,
                 other_specgram.times[-1].value))
         st = int(
             max(this_specgram.times[0].value,
                 other_specgram.times[0].value))
         this_specgram2 = this_specgram.crop(st, et)
         other_specgram2 = other_specgram.crop(st, et)
         newmat = this_specgram2.value * other_specgram2.value
         final_times = this_specgram2.times.value
     else:
         for ii, time in enumerate(self.times):
             # check if time appears in other specgram
             if np.isin(time, other.times):
                 # find where it appears
                 other_idx = np.where(other.times == time)[0]
                 # do cross-corr
                 newmat[ii, :] = this_specgram[ii, :].value *\
                     other_specgram[other_idx, :].value
                 # add this to final times list
                 final_times.append(time)
     # return
     return Spectrogram(newmat.squeeze(),
                        dt=(final_times[2] - final_times[1]),
                        t0=final_times[0],
                        f0=this_specgram.f0,
                        df=this_specgram.df,
                        unit=this_specgram.unit,
                        name=this_specgram.name + other_specgram.name,
                        channel=None)
Exemplo n.º 23
0
def stamp_variance(channel1, channel2, stride):
    """
    calculates stamp-pem variance from two time-series.
    Parameters
    ----------
        channel1 : TimeSeries or Spectrogram object
            timeseries or PSD for channel 1
        channel2 : TimeSeries or Spectrogram object
            timeseries or PSD for channel 2
        stride : int
            fft stride
    Returns
    -------
        stamp variance : Spectrogram object
    """
    # set units
    if isinstance(channel1, TimeSeries):
        psd1 = psdgram(channel1, stride)
    else:
        psd1 = channel1
    if isinstance(channel2, TimeSeries):
        psd2 = psdgram(channel2, stride)
    else:
        psd2 = channel2
    # set units
    if psd1.unit and psd2.unit:
        var_unit = psd1.unit * psd2.unit
    else:
        var_unit = (u.Hz)**-2
    variance = Spectrogram(0.5 * psd1.value * psd2.value,
                           epoch=psd1.epoch,
                           dt=psd1.dt,
                           copy=True,
                           unit=var_unit,
                           f0=psd1.f0,
                           df=psd1.df)
    return variance
Exemplo n.º 24
0
def read_data_archive(sourcefile):
    """Read archived data from an HDF5 archive source.

    Parameters
    ----------
    sourcefile : `str`
        path to source HDF5 file
    """
    from h5py import File

    with File(sourcefile, 'r') as h5file:
        # read all time-series data
        try:
            group = h5file['timeseries']
        except KeyError:
            group = dict()
        for dataset in group.itervalues():
            ts = TimeSeries.read(dataset, format='hdf')
            if (re.search('\.(rms|min|mean|max|n)\Z', ts.channel.name) and
                    ts.sample_rate.value == 1.0):
                ts.channel.type = 's-trend'
            elif re.search('\.(rms|min|mean|max|n)\Z', ts.channel.name):
                ts.channel.type = 'm-trend'
            ts.channel = get_channel(ts.channel)
            try:
                add_timeseries(ts, key=ts.channel.ndsname)
            except ValueError:
                if mode.get_mode() == mode.SUMMARY_MODE_DAY:
                    raise
                warnings.warn('Caught ValueError in combining daily archives')
                # get end time
                globalv.DATA[ts.channel.ndsname].pop(-1)
                t = globalv.DATA[ts.channel.ndsname][-1].span[-1]
                add_timeseries(ts.crop(start=t), key=ts.channel.ndsname)

        # read all state-vector data
        try:
            group = h5file['statevector']
        except KeyError:
            group = dict()
        for dataset in group.itervalues():
            sv = StateVector.read(dataset, format='hdf')
            sv.channel = get_channel(sv.channel)
            add_timeseries(sv, key=sv.channel.ndsname)

        # read all spectrogram data
        try:
            group = h5file['spectrogram']
        except KeyError:
            group = dict()
        for key, dataset in group.iteritems():
            key = key.rsplit(',', 1)[0]
            spec = Spectrogram.read(dataset, format='hdf')
            spec.channel = get_channel(spec.channel)
            add_spectrogram(spec, key=key)

        try:
            group = h5file['segments']
        except KeyError:
            group = dict()
        for name, dataset in group.iteritems():
            dqflag = DataQualityFlag.read(dataset, format='hdf')
            globalv.SEGMENTS += {name: dqflag}
Exemplo n.º 25
0
def fftgram(timeseries, stride, pad=False):
    """
    calculates fourier-gram with automatic
    50% overlapping hann windowing.
    Parameters
    ----------
        timeseries : gwpy TimeSeries
            time series to take fftgram of
        stride : `int`
            number of seconds in single PSD
    Returns
    -------
        fftgram : gwpy spectrogram
            a fourier-gram
    """

    fftlength = stride
    dt = stride
    df = 1. / fftlength
    # number of values in a step
    stride *= timeseries.sample_rate.value
    # number of steps
    nsteps = 2 * int(timeseries.size // stride) - 1
    # only get positive frequencies
    if pad:
        nfreqs = int(fftlength * timeseries.sample_rate.value)
        df = df / 2
        f0 = df
    else:
        nfreqs = int(fftlength * timeseries.sample_rate.value) / 2
    dtype = np.complex
    # initialize the spectrogram
    out = Spectrogram(np.zeros((nsteps, nfreqs), dtype=dtype),
                      name=timeseries.name,
                      epoch=timeseries.epoch,
                      f0=df,
                      df=df,
                      dt=dt,
                      copy=True,
                      unit=1 / u.Hz**0.5,
                      dtype=dtype)
    # stride through TimeSeries, recording FFTs as columns of Spectrogram
    for step in range(nsteps):
        # indexes for this step
        idx = (stride / 2) * step
        idx_end = idx + stride
        stepseries = timeseries[idx:idx_end]
        # zeropad, window, fft, shift zero to center, normalize
        # window
        stepseries = np.multiply(stepseries, np.hanning(stepseries.value.size))
        # take fft
        if pad:
            stepseries = TimeSeries(np.hstack(
                (stepseries, np.zeros(stepseries.size))),
                                    name=stepseries.name,
                                    x0=stepseries.x0,
                                    dx=timeseries.dx)
            tempfft = stepseries.fft(stepseries.size)
        else:
            tempfft = stepseries.fft(stepseries.size)
        tempfft.override_unit(out.unit)

        out[step] = tempfft[1:]

    return out
Exemplo n.º 26
0
def coherence_spectrogram(channel1,
                          channel2,
                          stride,
                          segmentDuration,
                          overlap=None,
                          pad=False,
                          st=None,
                          et=None):
    """
    Calculates coherence spectrogram for two channels.
    Can be called in two ways: either channel 1 and
    channel 2 are channel names or they are time series.
    If they are strings, then each segment is loaded
    separately as a way to save memory.

    TODO: This function is way too complicated. Just give it a single
    calling method.

    Parameters
    ----------
    channel 1 : `str` or TimeSeries object
        channel 1 name or time series
    channel 2 : `str` or TimeSeries object
        channel 2 name or time series
    stride : `int`
        stride for individual ffts (in seconds)
    segmentDuration : `int`
        duration of segments in spectrogram (in seconds)
    overlap : `int`, optional
        amount of overlap between ffts (in seconds)
    pad : `bool`, optional
        decide whether or not to pad ffts for taking csd
    frames : `bool`, optional
        decide whether to use frames or nds2 to load data
    st : `int`, optional
        start time if we're loading channel 1 and channel 2
        segments on the fly
    et : `int`, optional
        end time if we're loading channel 1 and channel 2 on the fly

    Returns
    -------
    coherence_spectrogram : Spectrogram object
        coherence spectrogram between channels 1 and 2
    psd1_spectrogram : Spectrogram object
        channel 1 psd spectrogram
    psd2_spectrogram : Spectrogram object
        channel 2 psd spectrogram
    N : `int`
        number of averages used for each pixel
    """
    if isinstance(channel1, TimeSeries):
        nsegs = (channel1.times.value[-1] - channel1.times.value[0]) \
            / segmentDuration
        nfreqs = min(channel1.sample_rate.value,
                     channel2.sample_rate.value) * stride * 0.5
        epoch = channel1.epoch
    elif isinstance(channel1, str):
        nsegs = int((et - st) / segmentDuration)
        test1 = _read_data(channel1, st, st + 1)
        test2 = _read_data(channel2, st, st + 1)
        nfreqs = int(
            min(test1.sample_rate.value, test2.sample_rate.value) * (stride) *
            0.5)
        epoch = test1.epoch

    df = 1. / stride

    coherence_spectrogram = Spectrogram(np.zeros((nsegs, nfreqs)),
                                        epoch=epoch,
                                        dt=segmentDuration,
                                        df=df,
                                        f0=df)
    psd1_spectrogram = Spectrogram(np.zeros((nsegs, nfreqs)),
                                   epoch=epoch,
                                   dt=segmentDuration,
                                   df=df,
                                   f0=df,
                                   unit=u.Hz**-1)
    psd2_spectrogram = Spectrogram(np.zeros((nsegs, nfreqs)),
                                   epoch=epoch,
                                   dt=segmentDuration,
                                   df=df,
                                   f0=df,
                                   unit=u.Hz**-1)
    if isinstance(channel1, str) and isinstance(channel2, str):
        for i in range(int(nsegs)):
            startTime = st + i * segmentDuration
            endTime = startTime + segmentDuration
            stepseries1 = _read_data(
                channel1,
                startTime,
                endTime,
            )
            stepseries2 = _read_data(
                channel2,
                startTime,
                endTime,
            )
            test, csd12, psd1, psd2, N = coherence(stepseries1,
                                                   stepseries2,
                                                   stride,
                                                   overlap=None,
                                                   pad=pad)
            coherence_spectrogram[i] = test
            psd1_spectrogram[i] = psd1
            psd2_spectrogram[i] = psd2
    else:
        samples1 = segmentDuration * channel1.sample_rate.value
        samples2 = segmentDuration * channel2.sample_rate.value
        for i in range(int(nsegs)):
            idx_start1 = samples1 * i
            idx_end1 = idx_start1 + samples1
            idx_start2 = samples2 * i
            idx_end2 = idx_start2 + samples2
            stepseries1 = channel1[idx_start1:idx_end1]
            stepseries2 = channel2[idx_start2:idx_end2]
            test, csd12, psd1, psd2, N = coherence(stepseries1,
                                                   stepseries2,
                                                   stride,
                                                   overlap=None,
                                                   pad=pad)
            coherence_spectrogram[i] = test
            psd1_spectrogram[i] = psd1
            psd2_spectrogram[i] = psd2

    return coherence_spectrogram, psd1_spectrogram, psd2_spectrogram, N
Exemplo n.º 27
0
def read_data_archive(sourcefile):
    """Read archived data from an HDF5 archive source

    This method reads all found data into the data containers defined by
    the `gwsumm.globalv` module, then returns nothing.

    Parameters
    ----------
    sourcefile : `str`
        path to source HDF5 file
    """
    from h5py import File

    with File(sourcefile, 'r') as h5file:

        # -- channels ---------------------------

        try:
            ctable = Table.read(h5file['channels'])
        except KeyError:  # no channels table written
            pass
        else:
            for row in ctable:
                chan = get_channel(row['name'])
                for p in ctable.colnames[1:]:
                    if row[p]:
                        setattr(chan, p, row[p])

        # -- timeseries -------------------------

        for dataset in h5file.get('timeseries', {}).values():
            ts = TimeSeries.read(dataset, format='hdf5')
            if (re.search(r'\.(rms|min|mean|max|n)\Z', ts.channel.name)
                    and ts.sample_rate.value == 1.0):
                ts.channel.type = 's-trend'
            elif re.search(r'\.(rms|min|mean|max|n)\Z', ts.channel.name):
                ts.channel.type = 'm-trend'
            ts.channel = get_channel(ts.channel)
            try:
                add_timeseries(ts, key=ts.channel.ndsname)
            except ValueError:
                if mode.get_mode() != mode.Mode.day:
                    raise
                warnings.warn('Caught ValueError in combining daily archives')
                # get end time
                globalv.DATA[ts.channel.ndsname].pop(-1)
                t = globalv.DATA[ts.channel.ndsname][-1].span[-1]
                add_timeseries(ts.crop(start=t), key=ts.channel.ndsname)

        # -- statevector -- ---------------------

        for dataset in h5file.get('statevector', {}).values():
            sv = StateVector.read(dataset, format='hdf5')
            sv.channel = get_channel(sv.channel)
            add_timeseries(sv, key=sv.channel.ndsname)

        # -- spectrogram ------------------------

        for tag, add_ in zip(
            ['spectrogram', 'coherence-components'],
            [add_spectrogram, add_coherence_component_spectrogram]):
            for key, dataset in h5file.get(tag, {}).items():
                key = key.rsplit(',', 1)[0]
                spec = Spectrogram.read(dataset, format='hdf5')
                spec.channel = get_channel(spec.channel)
                add_(spec, key=key)

        # -- segments ---------------------------

        for name, dataset in h5file.get('segments', {}).items():
            dqflag = DataQualityFlag.read(h5file,
                                          path=dataset.name,
                                          format='hdf5')
            globalv.SEGMENTS += {name: dqflag}

        # -- triggers ---------------------------

        for dataset in h5file.get('triggers', {}).values():
            load_table(dataset)
Exemplo n.º 28
0
    def spectrogram2(self, fftlength, overlap=0, window='hanning',
                     scaling='density', **kwargs):
        """Calculate the non-averaged power `Spectrogram` of this `TimeSeries`

        Parameters
        ----------
        fftlength : `float`
            number of seconds in single FFT.
        overlap : `float`, optional
            number of seconds between FFTs.
        window : `str` or `tuple` or `array-like`, optional
            desired window to use. See `~scipy.signal.get_window` for a list
            of windows and required parameters. If `window` is array_like it
            will be used directly as the window.
        scaling : [ 'density' | 'spectrum' ], optional
            selects between computing the power spectral density ('density')
            where the `Spectrogram` has units of V**2/Hz if the input is
            measured in V and computing the power spectrum ('spectrum')
            where the `Spectrogram` has units of V**2 if the input is
            measured in V. Defaults to 'density'.
        **kwargs
            other parameters to be passed to `scipy.signal.periodogram` for
            each column of the `Spectrogram`

        Returns
        -------
        spectrogram: `~gwpy.spectrogram.Spectrogram`
            a power `Spectrogram` with `1/fftlength` frequency resolution and
            (fftlength - overlap) time resolution.

        See also
        --------
        scipy.signal.periodogram
            for documentation on the Fourier methods used in this calculation

        Notes
        -----
        This method calculates overlapping periodograms for all possible
        chunks of data entirely containing within the span of the input
        `TimeSeries`, then normalises the power in overlapping chunks using
        a triangular window centred on that chunk which most overlaps the
        given `Spectrogram` time sample.
        """
        from ..spectrogram import Spectrogram
        from ..spectrum import scale_timeseries_units
        # get parameters
        sampling = units.Quantity(self.sample_rate, 'Hz').value
        if isinstance(fftlength, units.Quantity):
            fftlength = units.Quantity(fftlength, 's').value
        if isinstance(overlap, units.Quantity):
            overlap = units.Quantity(overlap, 's').value

        # sanity check
        if fftlength > abs(self.span):
            raise ValueError("fftlength cannot be greater than the duration "
                             "of this TimeSeries")
        if overlap >= fftlength:
            raise ValueError("overlap must be less than fftlength")

        # convert to samples
        nfft = int(fftlength * sampling)  # number of points per FFT
        noverlap = int(overlap * sampling)  # number of points of overlap
        nstride = nfft - noverlap  # number of points between FFTs

        # create output object
        nsteps = 1 + int((self.size - nstride) / nstride)  # number of columns
        nfreqs = int(nfft / 2 + 1)  # number of rows
        unit = scale_timeseries_units(self.unit, scaling)
        dt = nstride * self.dt
        tmp = numpy.zeros((nsteps, nfreqs), dtype=self.dtype)
        out = Spectrogram(numpy.zeros((nsteps, nfreqs), dtype=self.dtype),
                          epoch=self.epoch, channel=self.channel,
                          name=self.name, unit=unit, dt=dt, f0=0,
                          df=1/fftlength)

        # get window
        if window is None:
            window = 'boxcar'
        if isinstance(window, (str, tuple)):
            window = signal.get_window(window, nfft)

        # calculate overlapping periodograms
        for i in xrange(nsteps):
            idx = i * nstride
            # don't proceed past end of data, causes artefacts
            if idx+nfft > self.size:
                break
            ts = self.value[idx:idx+nfft]
            tmp[i, :] = signal.periodogram(ts, fs=sampling, window=window,
                                           nfft=nfft, scaling=scaling,
                                           **kwargs)[1]
        # normalize for over-dense grid
        density = nfft//nstride
        weights = signal.triang(density)
        for i in xrange(nsteps):
            # get indices of overlapping columns
            x0 = max(0, i+1-density)
            x1 = min(i+1, nsteps-density+1)
            if x0 == 0:
                w = weights[-x1:]
            elif x1 == nsteps - density + 1:
                w = weights[:x1-x0]
            else:
                w = weights
            # calculate weighted average
            out.value[i, :] = numpy.average(tmp[x0:x1], axis=0, weights=w)

        return out
Exemplo n.º 29
0
def fftgram(timeseries, stride, overlap=None, pad=False):
    """
    calculates fourier-gram with auto 50% overlapping
    segments and hann windowed

    Parameters
    ----------
    timeseries : :py:mod:`gwpy.timeseries.TimeSeries`
        time series to take fftgram of
    stride : `int`
        number of seconds in single PSD
    overalp : `int`
        number of seconds of overlap. Defaults to half of stride.

    Returns
    -------
    fftgram : :py:mod:`gwpy.spectrogram.Spectrogram`
        a fourier-gram
    """

    fftlength = stride
    if overlap is None:
        overlap = stride / 2.
    dt = stride - overlap
    df = 1. / fftlength
    # number of values in a step
    stride *= timeseries.sample_rate.value
    overlap *= timeseries.sample_rate.value
    step = stride - overlap
    # number of steps
    nsteps = int(timeseries.size // step) - 1
    # only get positive frequencies
    if pad:
        nfreqs = int(fftlength * timeseries.sample_rate.value)
        df = df / 2
        f0 = df
    else:
        nfreqs = int(fftlength * timeseries.sample_rate.value) / 2
    dtype = np.complex
    # initialize the spectrogram
    out = Spectrogram(np.zeros((nsteps, nfreqs), dtype=dtype),
                      name=timeseries.name,
                      epoch=timeseries.epoch,
                      f0=df,
                      df=df,
                      dt=dt,
                      copy=True,
                      unit=u.Hz**(-0.5),
                      dtype=dtype)
    # stride through TimeSeries, recording FFTs as columns of Spectrogram
    if (timeseries.sample_rate.value * stride) % 1:
        raise ValueError('1/stride must evenly divide sample rate of channel')
    for step in range(nsteps):
        # indexes for this step
        idx = int((stride / 2) * step)
        idx_end = int(idx + stride)
        stepseries = timeseries[idx:idx_end]
        # zeropad, window, fft
        stepseries = np.multiply(stepseries, np.hanning(stepseries.value.size))
        # hann windowing normalization
        norm = np.sum(np.hanning(stepseries.value.size))
        if pad:
            stepseries = TimeSeries(np.hstack(
                (stepseries, np.zeros(stepseries.size))),
                                    name=stepseries.name,
                                    x0=stepseries.x0,
                                    dx=timeseries.dx)
            tempfft = stepseries.fft(stepseries.size)
        else:
            tempfft = stepseries.fft(stepseries.size)
        # reset proper unit
        tempfft.override_unit(out.unit)
        # normalize
        out[step] = tempfft[1:] / norm

    return out
Exemplo n.º 30
0
    def average_fft(self, fftlength=None, overlap=0, window=None):
        """Compute the averaged one-dimensional DFT of this `TimeSeries`.

        This method computes a number of FFTs of duration ``fftlength``
        and ``overlap`` (both given in seconds), and returns the mean
        average. This method is analogous to the Welch average method
        for power spectra.

        Parameters
        ----------
        fftlength : `float`
            number of seconds in single FFT, default, use
            whole `TimeSeries`

        overlap : `float`
            numbers of seconds by which to overlap neighbouring FFTs,
            by default, no overlap is used.

        window : `str`, :class:`numpy.ndarray`
            name of the window function to use, or an array of length
            ``fftlength * TimeSeries.sample_rate`` to use as the window.

        Returns
        -------
        out : complex-valued :class:`~gwpy.spectrum.Spectrum`
            the transformed output, with populated frequencies array
            metadata

        See Also
        --------
        :mod:`scipy.fftpack` for the definition of the DFT and conventions
        used.
        """
        from gwpy.spectrogram import Spectrogram
        # format lengths
        if fftlength is None:
            fftlength = self.duration
        if isinstance(fftlength, units.Quantity):
            fftlength = fftlength.value
        nfft = int((fftlength * self.sample_rate).decompose().value)
        noverlap = int((overlap * self.sample_rate).decompose().value)

        navg = divmod(self.size-noverlap, (nfft-noverlap))[0]

        # format window
        if window is None:
            window = 'boxcar'
        if isinstance(window, str) or type(window) is tuple:
            win = signal.get_window(window, nfft)
        else:
            win = numpy.asarray(window)
            if len(win.shape) != 1:
                raise ValueError('window must be 1-D')
            elif win.shape[0] != nfft:
                raise ValueError('Window is the wrong size.')
        scaling = 1. / numpy.absolute(win).mean()

        if nfft % 2:
            nfreqs = (nfft + 1) // 2
        else:
            nfreqs = nfft // 2 + 1
        ffts = Spectrogram(numpy.zeros((navg, nfreqs), dtype=numpy.complex),
                           channel=self.channel, epoch=self.epoch, f0=0,
                           df=1 / fftlength, dt=1, copy=True)
        # stride through TimeSeries, recording FFTs as columns of Spectrogram
        idx = 0
        for i in range(navg):
            # find step TimeSeries
            idx_end = idx + nfft
            if idx_end > self.size:
                continue
            stepseries = self[idx:idx_end]
            # detrend
            stepseries -= stepseries.value.mean()
            # window
            stepseries *= win.astype(stepseries.dtype)
            # calculated FFT, weight, and stack
            fft_ = stepseries.fft(nfft=nfft) * scaling
            ffts.value[i, :] = fft_.value
            idx += (nfft - noverlap)
        mean = ffts.mean(0)
        mean.name = self.name
        mean.epoch = self.epoch
        mean.channel = self.channel
        return mean
Exemplo n.º 31
0
def read_data_archive(sourcefile):
    """Read archived data from an HDF5 archive source.

    Parameters
    ----------
    sourcefile : `str`
        path to source HDF5 file
    """
    from h5py import File

    with File(sourcefile, 'r') as h5file:
        # read all time-series data
        try:
            group = h5file['timeseries']
        except KeyError:
            group = dict()
        for dataset in group.itervalues():
            ts = TimeSeries.read(dataset, format='hdf5')
            if (re.search('\.(rms|min|mean|max|n)\Z', ts.channel.name)
                    and ts.sample_rate.value == 1.0):
                ts.channel.type = 's-trend'
            elif re.search('\.(rms|min|mean|max|n)\Z', ts.channel.name):
                ts.channel.type = 'm-trend'
            ts.channel = get_channel(ts.channel)
            try:
                add_timeseries(ts, key=ts.channel.ndsname)
            except ValueError:
                if mode.get_mode() != mode.Mode.day:
                    raise
                warnings.warn('Caught ValueError in combining daily archives')
                # get end time
                globalv.DATA[ts.channel.ndsname].pop(-1)
                t = globalv.DATA[ts.channel.ndsname][-1].span[-1]
                add_timeseries(ts.crop(start=t), key=ts.channel.ndsname)

        # read all state-vector data
        try:
            group = h5file['statevector']
        except KeyError:
            group = dict()
        for dataset in group.itervalues():
            sv = StateVector.read(dataset, format='hdf5')
            sv.channel = get_channel(sv.channel)
            add_timeseries(sv, key=sv.channel.ndsname)

        # read all spectrogram data
        for tag in ['spectrogram', 'coherence-components']:
            if tag == 'coherence-components':
                add_ = add_coherence_component_spectrogram
            else:
                add_ = add_spectrogram
            try:
                group = h5file[tag]
            except KeyError:
                group = dict()
            for key, dataset in group.iteritems():
                key = key.rsplit(',', 1)[0]
                spec = Spectrogram.read(dataset, format='hdf5')
                spec.channel = get_channel(spec.channel)
                add_(spec, key=key)

        # read all segments
        try:
            group = h5file['segments']
        except KeyError:
            group = dict()
        for name in group:
            dqflag = DataQualityFlag.read(group, path=name, format='hdf5')
            globalv.SEGMENTS += {name: dqflag}

        # read all triggers
        try:
            group = h5file['triggers']
        except KeyError:
            group = dict()
        for key in group:
            load_table(group[key])
Exemplo n.º 32
0
def get_channel_online_data(
        channel,
        st,
        et,
        format='spectrogram',
        remove_nonlocked_times=False,
        normalize_coherence=False,
        config_file='/home/stochastic/config_files/ini_files/H1.ini'):
    """
    Returns a list of PEMCoherenceSegment
    objects.

    Parameters
    ----------
    channel : str
        channel name you want to load
    st : str or int
        start time (in string format) or gps time
    et : str or int
        end time (in string format) or gps time
    format : str, optional, default='spectrogram'
        format to return. either spectrogram or seglist. Spectrogram returns a
        `gwpy.spectrogram.Spectrogram` and seglist returns a list of
        `stamp_pem.coherence_segment.PEMCoherenceSegment`.
    remove_nonlocked_times: bool, optional, default=False
        Removes non locked times from a spectrogram
    normalize_coherence : bool, optional, default=False
        Normalizes each column of spectrogram by the number of averages

    Returns
    -------
    out : `gwpy.spectrogram.Spectrogram` or list of
    `stamp_pem.coherence_segment.PEMCoherencSegment` objects
        representation of data between start and end times for a given channel
    """
    pipeline_dict = coh_io.read_pipeline_ini(config_file)
    env_params, run_params = coh_io.check_ini_params(pipeline_dict)
    channel_dict = ChannelDict.read(env_params['list'])
    jobdur = int(env_params['job_duration'])
    darm_channel = run_params['darm_channel']
    basedir = env_params['base_directory']

    if isinstance(st, str):
        st = int(time.to_gps(st))
    if isinstance(et, str):
        et = int(time.to_gps(et))
    starttimes = np.arange(st, et, jobdur)
    subsys = get_channels_subsystem(channel, channel_dict)
    seglist = []
    for starttime in starttimes:
        cohdir = coh_io.get_directory_structure(subsys, starttime, basedir)
        cohfile = coh_io.create_coherence_data_filename(darm_channel,
                                                        subsys,
                                                        starttime,
                                                        starttime + jobdur,
                                                        directory=cohdir)
        try:
            subsystem_data = PEMSubsystem.read(subsys, cohfile)
        except IOError:
            print "No data found between %d and %d for %s" % (
                starttime, starttime + jobdur, channel)
            continue

        if np.isnan(subsystem_data[channel].psd1.value[0]):
            continue
        seglist.append(subsystem_data[channel])

    N = 1

    if format == 'spectrogram':
        if remove_nonlocked_times:
            foundtimes = np.asarray(
                [seglist[ii].starttime for ii in range(len(seglist))])
            data = np.zeros((len(seglist), seglist[0].psd1.size))
            for ii in range(len(seglist)):
                if normalize_coherence:
                    N = seglist[ii].N
                if seglist[ii].get_coh()[0] == np.nan:
                    continue
                data[ii, :] = seglist[ii].get_coh() * N
                specgram = Spectrogram(data,
                                       epoch=foundtimes[0],
                                       dt=jobdur,
                                       df=seglist[0].psd1.df)
        else:
            foundtimes = np.asarray(
                [seglist[ii].starttime for ii in range(len(seglist))])
            count = 0
            data = np.nan * np.zeros((starttimes.size, seglist[0].psd1.size))
            for ii, starttime in enumerate(starttimes):
                if np.any(foundtimes == starttime):
                    if normalize_coherence:
                        N = seglist[count].N
                    data[ii, :] = seglist[count].get_coh() * N
                    count += 1
            specgram = Spectrogram(data,
                                   dt=jobdur,
                                   epoch=starttimes[0],
                                   df=seglist[0].psd1.df)
        return specgram
    elif format == 'seglist':
        return seglist
    else:
        raise ValueError('format needs to be "spectrogram" or "seglist"')
Exemplo n.º 33
0
def read_data_archive(sourcefile):
    """Read archived data from an HDF5 archive source

    This method reads all found data into the data containers defined by
    the `gwsumm.globalv` module, then returns nothing.

    Parameters
    ----------
    sourcefile : `str`
        path to source HDF5 file
    """
    from h5py import File

    with File(sourcefile, 'r') as h5file:

        # -- channels ---------------------------

        try:
            ctable = Table.read(h5file['channels'])
        except KeyError:  # no channels table written
            pass
        else:
            for row in ctable:
                chan = get_channel(row['name'])
                for p in ctable.colnames[1:]:
                    if row[p]:
                        setattr(chan, p, row[p])

        # -- timeseries -------------------------

        for dataset in h5file.get('timeseries', {}).values():
            ts = TimeSeries.read(dataset, format='hdf5')
            if (re.search(r'\.(rms|min|mean|max|n)\Z', ts.channel.name) and
                    ts.sample_rate.value == 1.0):
                ts.channel.type = 's-trend'
            elif re.search(r'\.(rms|min|mean|max|n)\Z', ts.channel.name):
                ts.channel.type = 'm-trend'
            ts.channel = get_channel(ts.channel)
            try:
                add_timeseries(ts, key=ts.channel.ndsname)
            except ValueError:
                if mode.get_mode() != mode.Mode.day:
                    raise
                warnings.warn('Caught ValueError in combining daily archives')
                # get end time
                globalv.DATA[ts.channel.ndsname].pop(-1)
                t = globalv.DATA[ts.channel.ndsname][-1].span[-1]
                add_timeseries(ts.crop(start=t), key=ts.channel.ndsname)

        # -- statevector -- ---------------------

        for dataset in h5file.get('statevector', {}).values():
            sv = StateVector.read(dataset, format='hdf5')
            sv.channel = get_channel(sv.channel)
            add_timeseries(sv, key=sv.channel.ndsname)

        # -- spectrogram ------------------------

        for tag, add_ in zip(
                ['spectrogram', 'coherence-components'],
                [add_spectrogram, add_coherence_component_spectrogram]):
            for key, dataset in h5file.get(tag, {}).items():
                key = key.rsplit(',', 1)[0]
                spec = Spectrogram.read(dataset, format='hdf5')
                spec.channel = get_channel(spec.channel)
                add_(spec, key=key)

        # -- segments ---------------------------

        for name, dataset in h5file.get('segments', {}).items():
            dqflag = DataQualityFlag.read(h5file, path=dataset.name,
                                          format='hdf5')
            globalv.SEGMENTS += {name: dqflag}

        # -- triggers ---------------------------

        for dataset in h5file.get('triggers', {}).values():
            load_table(dataset)
Exemplo n.º 34
0
def csdgram(channel1, channel2, stride):
    """
    calculates one-sided csd spectrogram between two timeseries
    or fftgrams. Allows for flexibility for holding DARM
    fftgram in memory while looping over others.
    Parameters
    ----------
        channel1 : TimeSeries or Spectrogram object
            timeseries from channel 1
        timeseries2 : TimeSeries or Spectrogram object
            timeseries from channel 2
    Returns
    -------
        csdgram : spectrogram object
            csd spectrogram for two objects
    """
    if isinstance(channel1, TimeSeries):
        fftgram1 = fftgram(channel1, stride, pad=True)
    elif isinstance(channel1, Spectrogram):
        fftgram1 = channel1
    else:
        raise TypeError('First arg is either TimeSeries or Spectrogram object')
    if isinstance(channel2, TimeSeries):
        fftgram2 = fftgram(channel2, stride, pad=True)
    elif isinstance(channel2, Spectrogram):
        fftgram2 = channel2
    else:
        raise TypeError('First arg is either TimeSeries or Spectrogram object')

    # clip off first 2 and last 2 segments to be consistent with psd
    # calculation
    out = (fftgram1.value * np.conj(fftgram2.value))[2:-2]

    csdname = 'csd spectrogram between %s and %s' % (fftgram1.name,
                                                     fftgram2.name)
    out = Spectrogram(out,
                      name=csdname,
                      epoch=fftgram1.epoch.value + 2 * fftgram1.dt.value,
                      df=fftgram1.df,
                      dt=fftgram1.dt,
                      copy=True,
                      unit=fftgram1.unit * fftgram2.unit,
                      f0=fftgram1.f0)
    df = fftgram1.df.value * 2
    f0 = fftgram1.f0.value * 2
    csdgram = Spectrogram(np.zeros((out.shape[0], out.shape[1] / 2),
                                   dtype=np.complex),
                          df=df,
                          dt=fftgram1.dt,
                          copy=True,
                          unit=out.unit,
                          f0=f0,
                          epoch=out.epoch)

    for ii in range(csdgram.shape[0]):
        # multiply by 2 for one-sided spectrum
        temp = Spectrum(2 * out.data[ii],
                        df=out.df,
                        f0=out.f0,
                        epoch=out.epoch,
                        unit=out.unit)
        N = out.shape[1] / 2
        csdgram[ii] = coarseGrain(temp, df, f0, N)

    return csdgram
def generate_magnetometer_csd(ifoparams1, ifoparams2, generalparams,
                              stochparams):
    from datetime import datetime
    from astropy.time import Time
    # get start time and duration from our paramfile
    st = Time(datetime.strptime(generalparams['mag_day_start'], '%Y%m%d')).gps
    dur = int(float(generalparams['ndays']) * 86400)

    # general frame name
    rawmag_fname = generalparams[
        'output_prefix'] + '/correlated_mag_data/%s-RAW-MAG-DATA-%d-%d.gwf'

    # specific frame names
    rawmag_fname1 = rawmag_fname % (ifoparams1['name'], st, dur)
    rawmag_fname2 = rawmag_fname % (ifoparams2['name'], st, dur)

    # load them up
    magts1 = MagTimeSeries.read(str(rawmag_fname1),
                                '%s:mag_data' % ifoparams1['name'])
    magts2 = MagTimeSeries.read(str(rawmag_fname2),
                                '%s:mag_data' % ifoparams2['name'])

    # take csd spectrogram between two magnetic timeseries
    magcsd = magts1.csd_spectrogram(magts2,
                                    float(stochparams['segdur']),
                                    fftlength=float(stochparams['segdur']),
                                    overlap=float(stochparams['segdur']) / 2.,
                                    nproc=8)

    # generate hdf5 file name for output
    csd_fname = generalparams[
        'output_prefix'] + '/correlated_mag_data/%s-%s-COMPLEX-CSD-%d-%d.hdf5'

    # coarsegrain
    # note there's a gwpy bug for slicing on rows right now
    # it produces a FrequencySeries with the wrong metadata.
    # we'll fix it on the fly
    # TODO: open a GWpy issue about this problem

    # coarsegrain once to get shape
    ntimes = magcsd.shape[0]
    spec1 = coarseGrain(FrequencySeries(magcsd[0, :].value,
                                        df=magcsd.df,
                                        f0=magcsd.f0),
                        flowy=float(stochparams['deltaf']),
                        deltaFy=float(stochparams['deltaf']))

    # initialize array for speed
    # make sure to tell it you want a complex array
    # otherwise it'll automatically pick out
    # real part of what you put into it
    newarr = np.zeros((ntimes, spec1.size), dtype=complex)

    print('COARSEGRAINING MAG DATA FOR STOCHASTIC USE')

    # loop over each individual spectrum and coarse grain
    for ii in range(ntimes):
        newarr[ii, :] = coarseGrain(FrequencySeries(magcsd[ii, :].value,
                                                    df=magcsd.df,
                                                    f0=magcsd.f0),
                                    flowy=float(stochparams['deltaf']),
                                    deltaFy=float(stochparams['deltaf'])).value

    # create final spectrogram object
    final_csd = Spectrogram(newarr,
                            df=spec1.df,
                            f0=spec1.f0,
                            name=magcsd.name,
                            channel=magcsd.channel,
                            times=magcsd.times)

    # write to an hdf5 file
    final_csd.write(str(csd_fname %
                        (ifoparams1['name'], ifoparams2['name'], st, dur)),
                    overwrite=True)

    # add final message so you know where to look after
    print('WROTE CORRELATED SPECTROGRAM TO %s' %
          str(csd_fname % (ifoparams1['name'], ifoparams2['name'], st, dur)))
Exemplo n.º 36
0
def psdgram(timeseries, stride):
    """
    calculates one-sided PSD from timeseries
    properly using welch's method by averaging adjacent non-ovlping
    segments. Since default fftgram overlaps segments
    we have to be careful here...
    Parameters
    ----------
        fftgram : Spectrogram object
            complex fftgram
        adjacent : `int`
            number of adjacent segments
            to calculate PSD of middle segment
    Returns
    -------
        psdgram : Spectrogram object
            psd spectrogram calculated in
            spirit of STAMP/stochastic
    """
    fftlength = stride
    dt = stride
    df = 1. / fftlength
    # number of values in a step
    stride *= timeseries.sample_rate.value
    # number of steps
    nsteps = 2 * int(timeseries.size // stride) - 1
    # only get positive frequencies
    nfreqs = int(fftlength * timeseries.sample_rate.value) / 2.
    # initialize the spectrogram
    if timeseries.unit:
        unit = timeseries.unit / u.Hz
    else:
        unit = 1 / u.Hz
    out = Spectrogram(np.zeros((nsteps, int(nfreqs))),
                      name=timeseries.name,
                      epoch=timeseries.epoch,
                      f0=df / 2,
                      df=df,
                      dt=dt,
                      copy=True,
                      unit=unit)
    # stride through TimeSeries, recording FFTs as columns of Spectrogram
    for step in range(nsteps):
        # indexes for this step
        idx = (stride / 2) * step
        idx_end = idx + stride
        stepseries = timeseries[idx:idx_end]
        steppsd = stepseries.psd()[1:]
        out.value[step, :] = steppsd.value

    psdleft = np.hstack((out.T, np.zeros((out.shape[1], 4))))
    psdright = np.hstack((np.zeros((out.shape[1], 4)), out.T))
    psd_temp = ((psdleft + psdright) / 2).T
    # create spectrogram object. multiply by 2 for one-sided.
    psd = Spectrogram(2 * psd_temp.value[4:-4],
                      name=timeseries.name,
                      epoch=timeseries.epoch.value + 2 * dt,
                      f0=df,
                      df=df,
                      dt=dt,
                      copy=True,
                      unit=unit)
    return psd