def read(cls, subsys, filename): """ read from a file Parameters ---------- subsys : `str` Channel subsystem filename : `str` File to read from """ # open file if isinstance(filename, str): f = h5py.File(filename, 'r') else: f = filename chandict = {subsys: f[subsys].keys()} darm_channel = f['psd1'].keys()[0].split()[0].strip() ss = PEMSubsystem(subsys, darm_channel, chandict) psd1 = FrequencySeries.read(f['psd1'][f['psd1'].keys()[0]]) for channel in chandict[subsys]: N = int(f[subsys][channel]['metadata'][0, 1]) st = int(f[subsys][channel]['metadata'][1, 1]) et = int(f[subsys][channel]['metadata'][2, 1]) csd12 = FrequencySeries.read(f[subsys][channel]['csd mean']) psd2 = FrequencySeries.read(f[subsys][channel]['%s mean' % channel]) ss[channel] = PEMCoherenceSegment(darm_channel, channel, csd12, psd1, psd2, N, st, et) ss.failed_channels = f['failed_channels'][:] f.close() return ss
def mybode(*args, **kwargs): freq = kwargs.pop('freq', None) kwargs['omega'] = freq * 2.0 * np.pi mag, phase, omega = bode(*args, **kwargs) phase = degwrap(phase) mag = FrequencySeries(mag, frequencies=freq) phase = FrequencySeries(phase, frequencies=freq) return mag, phase
def test_read_ligolw(self): with tempfile.NamedTemporaryFile(mode='w+') as fobj: fobj.write(LIGO_LW_ARRAY) array = FrequencySeries.read( fobj, 'psd', match={'channel': 'X1:TEST-CHANNEL_1'}) utils.assert_array_equal(array, list(range(1, 11)) / units.Hz) utils.assert_array_equal(array.frequencies, list(range(10)) * units.Hz) assert numpy.isclose(array.epoch.gps, 1000000000) # precision gah! assert array.unit == units.Hz**-1 array2 = FrequencySeries.read( fobj, 'psd', match={'channel': 'X1:TEST-CHANNEL_2'}) assert array2.epoch is None # assert errors with pytest.raises(ValueError): FrequencySeries.read(fobj, 'blah') with pytest.raises(ValueError): FrequencySeries.read(fobj, 'psd') with pytest.raises(ValueError): FrequencySeries.read(fobj, 'psd', match={ 'channel': 'X1:TEST-CHANNEL_1', 'blah': 'blah' })
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
def _percentile(axis, pctl=50, unit='um', suffix='', _dir='', **kwargs): fname = './data2/{3}/{0}_{1}.hdf5'.format(axis, pctl, suffix, _dir) model = kwargs.pop('model', None) _asd = FrequencySeries.read(fname)**0.5 if model == '120QA': amp = 10**(30.0 / 20.0) elif model == 'compact': amp = 10**(45.0 / 20.0) seis = Trillium(model) v2vel = seis.v2vel c2v = 20.0 / 2**15 _asd = v2vel(_asd) * c2v / amp * 1e6 if unit == 'um': asd = _asd / (2.0 * np.pi * _asd.frequencies.value) #asd.write('./LongTerm_{0}_{1}_DISP.txt'.format(axis,pctl),format='txt') elif unit == 'm': asd = _asd / (2.0 * np.pi * _asd.frequencies.value) * 1e-6 asd.write('./{0}_{1}_DISP.txt'.format(axis, pctl), format='txt') elif unit == 'um/sec': asd = _asd asd.write('./{0}_{1}_VELO.txt'.format(axis, pctl), format='txt') elif unit == 'um/sec/sec': asd = _asd * (2.0 * np.pi * _asd.frequencies.value) #asd.write('./LongTerm_{0}_{1}_ACC.txt'.format(axis,pctl),format='txt') elif unit == 'm/sec/sec': asd = _asd * (2.0 * np.pi * _asd.frequencies.value) * 1e-6 else: raise ValueError('!!1', unit) return asd
def comb_finder(self, offsets, comb_widths, cutoff=None): """ Parameters ---------- offsets : `int` comb_widths : `int` cutoff : `bool`, optional Returns ------- :py:class:`CoherenceCombMatrix` object """ comb_mat = np.zeros((len(offsets), len(comb_widths))) likelihood_mat = np.zeros((len(offsets), len(comb_widths))) f0 = self.psd1.frequencies[0].value df = self.psd1.df.value coh = FrequencySeries(self.get_coh(cutoff=cutoff), frequencies=self.psd1.frequencies) for ii, offset in enumerate(offsets): start_idx = max(0, ((offset - f0) / df)) for jj, width in enumerate(comb_widths): mask = np.zeros(self.psd1.size, dtype=bool) comb_idx_width = width / np.float(df) mask[start_idx::comb_idx_width] = True comb_mat[ii, jj] = self.sum_coh(mask, cutoff=cutoff) likelihood_mat[ii, jj] = stats.gamma.logpdf( self.N * self.sum_coh(mask, cutoff=cutoff), np.sum(np.int_(mask))) * self.N return CoherenceCombMatrix(comb_mat, likelihood_mat, offsets, comb_widths, coh)
def _get_extended_metadata(h5group): """Extract the extended metadata for a PyCBC table in HDF5 This method packs non-table-column datasets in the given h5group into a metadata `dict` Returns ------- meta : `dict` the metadata dict """ meta = dict() # get PSD try: psd = h5group['psd'] except KeyError: pass else: from gwpy.frequencyseries import FrequencySeries meta['psd'] = FrequencySeries( psd[:], f0=0, df=psd.attrs['delta_f'], name='pycbc_live') # get everything else for key in META_COLUMNS - {'psd'}: try: value = h5group[key][:] except KeyError: pass else: meta[key] = value return meta
def load_strain_data(self, cache=True): """ Load the strain data for the event If it doesn't exist already, then it will be downloaded into the strain_data folder INPUTS ------ cache: bool if True, then store local copy of strain data passed to pesummary StrainData.fetch_open_data """ self.data = {} self.data_w = {} for IFO in self.IFOs: # download public strain data print("Downloading strain data for " + IFO) self.data[IFO] = StrainData.fetch_open_data(IFO, self.t_start, self.t_end, cache=cache) # unpack PSD into FrequencySeries ASD object fS = np.array(self.psd[IFO]) asd = FrequencySeries(np.sqrt(fS[:, 1]), frequencies=fS[:, 0]) # whitened strain self.data_w[IFO] = self.data[IFO].whiten(asd=asd)
def tf(sys,omega): mag, phase, omega = matlab.bode(sys,omega,Plot=False) mag = np.squeeze(mag) phase = np.squeeze(phase) G = mag*np.exp(1j*phase) freq = omega/(2.0*np.pi) hoge = FrequencySeries(G,frequencies=freq) return hoge
def inner_product(data1,data2): assert data1.duration==data2.duration srate1=data1.sample_rate.value srate2=data2.sample_rate.value fdata1=rfft(sig.hann(len(data1))*data1.detrend().value) fdata2=rfft(sig.hann(len(data2))*data2.detrend().value) max_idx=min(len(fdata1),len(fdata2)) return FrequencySeries(fdata1[:max_idx]*fdata2.conjugate()[:max_idx], df=1./data1.duration)
def read(fname): try: data = FrequencySeries.read(fname, format='hdf5') except IOError as ioe: print(ioe) exit() else: pass return data
def avg_freq_bins(fdata,new_df): nyquist=(len(fdata)-1)*fdata.df.value new_flen=1+int(nyquist/float(new_df)) binlen=int(new_df/float(fdata.df.value)) win=sig.hann(2*binlen) win/=np.sum(win) result=np.zeros(new_flen,dtype=fdata.dtype) for idx in range(1,new_flen-1): result[idx]=np.sum(win*fdata.value[binlen*(idx-1):binlen*(idx+1)]) return FrequencySeries(result,df=new_df,channel=fdata.channel, name=fdata.name,epoch=fdata.epoch)
def test_inject(self): # create a timeseries out of an array of zeros df, nyquist = 1, 2048 data = FrequencySeries(numpy.zeros(df*nyquist + 1), f0=0, df=df, unit='') # create a second timeseries to inject into the first w_nyquist = 1024 sig = FrequencySeries(numpy.ones(df*w_nyquist + 1), f0=0, df=df, unit='') # test that we recover this waveform when we add it to data, # and that the operation does not change the original data new_data = data.inject(sig) assert new_data.unit == data.unit assert new_data.size == data.size ind, = new_data.value.nonzero() assert len(ind) == sig.size utils.assert_allclose(new_data.value[ind], sig.value) utils.assert_allclose(data.value, numpy.zeros(df*nyquist + 1))
def plot_spectrum(fd_psd): ''' Plot power spectral density ''' plot = FrequencySeriesPlot() ax = plot.gca() ax.plot(FrequencySeries(fd_psd, df=fd_psd.delta_f)) #plt.ylim(1e-10, 1e-3) plt.xlim(0.1, 500) plt.loglog() plt.savefig("psd.png", dpi=300, transparent=True) plt.close()
def test_add_arrays(self): ts = TimeSeries([1, 2, 3, 4]) fs = FrequencySeries([1, 2, 3, 4]) fig = self.FIGURE_CLASS() self.assertEqual(len(fig.axes), 0) fig.add_timeseries(ts) self.assertEqual(len(fig.axes), 1) self.assertIsInstance(fig.axes[0], TimeSeriesAxes) fig.add_frequencyseries(fs) self.assertEqual(len(fig.axes), 2) self.assertIsInstance(fig.axes[1], FrequencySeriesAxes) fig.close()
def dataprod(cls, prod): super(_TestFrequencyDomainProduct, cls).dataprod(prod) fftlength = prod.args.secpfft for ts in prod.timeseries: nsamp = int(fftlength * 512 / 2.) + 1 fs = FrequencySeries(_random_data(nsamp), x0=0, dx=1 / fftlength, channel=ts.channel, name=ts.name) prod.spectra.append(fs) return prod
def to_gwpy_frequencyseries(self): """ Output the frequency series strain data as a :class:`gwpy.frequencyseries.FrequencySeries`. """ try: from gwpy.frequencyseries import FrequencySeries except ModuleNotFoundError: raise ModuleNotFoundError( "Cannot output strain data as gwpy FrequencySeries") return FrequencySeries(self.frequency_domain_strain, frequencies=self.frequency_array, epoch=self.start_time, channel=self.channel)
def test_add_arrays(self): ts = TimeSeries([1, 2, 3, 4]) fs = FrequencySeries([1, 2, 3, 4]) fig = self.FIGURE_CLASS() assert len(fig.axes) == 0 fig.add_timeseries(ts) assert len(fig.axes) == 1 assert isinstance(fig.axes[0], TimeSeriesAxes) fig.add_frequencyseries(fs) assert len(fig.axes) == 2 assert isinstance(fig.axes[1], FrequencySeriesAxes) fig.close()
def read_frequencyseries(filename): """Read a `~gwpy.frequencyseries.FrequencySeries` from a file IF using HDF5, the filename can be given as a combined filename/path, i.e. ``test.hdf5/path/to/dataset``. Parameters ---------- filename : `str` path of file to read Returns ------- series : `~gwpy.frequencyseries.FrequencySeries` the data as read Raises ------ astropy.io.registry.IORegistryError if the input format cannot be identified or is not registered """ # try and parse path in HDF5 file if given try: ext = HDF5_FILENAME.search(filename).groupdict()['ext'] except AttributeError: # no match kwargs = {} else: kwargs = {'path': filename.rsplit(ext, 1)[1]} # read file try: return FrequencySeries.read(filename, **kwargs) except IORegistryError: if filename.endswith('.gz'): fmt = os.path.splitext(filename[:-3])[-1] else: fmt = os.path.splitext(filename)[-1] return FrequencySeries.read(filename, format=fmt.lstrip('.'), **kwargs)
def read_frequencyseries(filename): """Read a `~gwpy.frequencyseries.FrequencySeries` from a file IF using HDF5, the filename can be given as a combined filename/path, i.e. ``test.hdf5/path/to/dataset``. Parameters ---------- filename : `str` path of file to read Returns ------- series : `~gwpy.frequencyseries.FrequencySeries` the data as read Raises ------ astropy.io.registry.IORegistryError if the input format cannot be identified or is not registered """ # try and parse path in HDF5 file if given try: ext = HDF5_FILENAME.search(filename).groupdict()['ext'] except AttributeError: # no match kwargs = {} else: kwargs = {'path': filename.rsplit(ext, 1)[1]} # read file try: return FrequencySeries.read(filename, **kwargs) except IORegistryError as e: if filename.endswith('.gz'): fmt = os.path.splitext(filename[:-3])[-1] else: fmt = os.path.splitext(filename)[-1] return FrequencySeries.read(filename, format=fmt.lstrip('.'), **kwargs)
def test_inject(self): # create a timeseries out of an array of zeros df, nyquist = 1, 2048 data = FrequencySeries(numpy.zeros(df * nyquist + 1), f0=0, df=df, unit='') # create a second timeseries to inject into the first w_nyquist = 1024 sig = FrequencySeries(numpy.ones(df * w_nyquist + 1), f0=0, df=df, unit='') # test that we recover this waveform when we add it to data, # and that the operation does not change the original data new_data = data.inject(sig) assert new_data.unit == data.unit assert new_data.size == data.size ind, = new_data.value.nonzero() assert len(ind) == sig.size utils.assert_allclose(new_data.value[ind], sig.value) utils.assert_allclose(data.value, numpy.zeros(df * nyquist + 1))
def kagra_seis(axis='X', pctl=90): if axis in ['X', 'Y', 'Z']: prefix = '/Users/miyo/Git/miyopy/miyopy/seismodel/JGW-T1910436-v5/' fname = 'LongTerm_{axis}_{pctl}_VELO.txt'.format(axis=axis, pctl=pctl) vel_asd = FrequencySeries.read(prefix + fname) return vel_asd elif axis == 'H': vel_x = kagra_seis('X', pctl) vel_y = kagra_seis('Y', pctl) vel_h = (vel_x**2 + vel_y**2)**(1. / 2) return vel_h elif axis == 'V': return kagra_seis('Z', pctl) else: raise ValueError('hoge')
def _percentile(axis, pctl=50, unit='um/sec', **kwargs): _asd = FrequencySeries.read('./data2/LongTerm_{0}_{1}.hdf5'.format( axis, pctl))**0.5 amp = 10**(30.0 / 20.0) c2v = 20.0 / 2**15 _asd = v2vel(_asd) * c2v / amp * 1e6 if unit == 'um': asd = _asd / (2.0 * np.pi * _asd.frequencies.value) #asd.write('./LongTerm_{0}_{1}_DISP.txt'.format(axis,pctl),format='txt') elif unit == 'um/sec': asd = _asd #asd.write('./LongTerm_{0}_{1}_VELO.txt'.format(axis,pctl),format='txt') else: raise ValueError('!!1') return asd
def to_pycbc_frequencyseries(self): """ Output the frequency series strain data as a :class:`pycbc.types.frequencyseries.FrequencySeries`. """ try: from pycbc.types.frequencyseries import FrequencySeries from lal import LIGOTimeGPS except ImportError: raise ImportError( "Cannot output strain data as PyCBC FrequencySeries") return FrequencySeries(self.frequency_domain_strain, delta_f=1 / self.duration, epoch=LIGOTimeGPS(self.start_time))
def plot_spectra(clusters, channel, unit='cts', xlog=True, legend=None, xlim=None, **kwargs): from glob import glob from gwpy.frequencyseries import FrequencySeries from gwpy.plot import Plot title = channel psds = {} for cluster in clusters: for filename in glob('*.hdf5'): try: psds[cluster] = FrequencySeries.read(filename, f'{cluster}-{channel}') print(f'found in {filename}') break except KeyError: continue else: raise KeyError(f'Could not find Nº{cluster}') if legend is None: legend = clusters # plot the group in one figure. plt = Plot(*(psds[cluster] for cluster in psds), separate=False, sharex=True, zorder=1, **kwargs) if xlim is not None: plt.gca().set_xlim(xlim) plt.gca().set_ylim((1e-48, 1e-37)) # modify the figure as a whole. # plt.add_segments_bar(dq, label='') # plt.gca().set_color_cycle(['red', 'green', 'blue', 'yellow']) if xlog: plt.gca().set_xscale('log') plt.gca().set_yscale('log') plt.gca().set_ylabel(f'Power Spectral Density [{unit}^2/Hz]') plt.suptitle(title) plt.legend(legend, prop={'size': 15}) # save to png. plt.save(f'{title}.png')
def _gen_white_gaussian_noise(cls, station_names, psd_amp, sample_rate, duration, segdur=None, seed=None): if segdur is None: segdur=duration data = SeismometerArray() psd = FrequencySeries(psd_amp * np.ones(100000), df=1./(segdur)) psd[0]=0 for station in station_names: data[station] = Seismometer.initialize_all_good(duration=segdur) # set data channels to white noise data[station]['HHE'] = gaussian.noise_from_psd(duration, sample_rate, psd, seed=seed, name=station, unit=u.m) data[station]['HHN'] = gaussian.noise_from_psd(duration, sample_rate, psd, seed=seed, name=station, unit=u.m) data[station]['HHZ'] = gaussian.noise_from_psd(duration, sample_rate, psd, seed=seed, name=station, unit=u.m) return data
def _percentile(axis, pctl=50, unit='um/sec', **kwargs): suffix = '_{0}_{1}'.format(start, end) fname = fname_hdf5_longasd(axis, pctl, suffix=suffix, prefix='./tmp') _asd = FrequencySeries.read(fname)**0.5 amp = 10**(30.0 / 20.0) c2v = 20.0 / 2**15 _asd = v2vel(_asd) * c2v / amp * 1e6 if unit == 'um': asd = _asd / (2.0 * np.pi * _asd.frequencies.value) asd.write('./LongTerm_{0}_{1}_DISP.txt'.format(axis, pctl), format='txt') elif unit == 'um/sec': asd = _asd asd.write('./LongTerm_{0}_{1}_VELO.txt'.format(axis, pctl), format='txt') else: raise ValueError('!!1') return asd
def get_range_spectrum(channel, segments, config=None, cache=None, query=True, nds=None, return_=True, nproc=1, datafind_error='raise', frametype=None, stride=60, fftlength=None, overlap=None, method=None, which='all', **rangekwargs): """Compute percentile spectra of the range integrand from a set of spectrograms """ name = str(channel) cmin = '%s.min' % name cmax = '%s.max' % name if name not in globalv.SPECTRUM: speclist = get_range_spectrogram( channel, segments, config=config, cache=cache, query=query, nds=nds, return_=return_, nproc=nproc, frametype=frametype, datafind_error=datafind_error, method=method, stride=stride, fftlength=fftlength, overlap=overlap, **rangekwargs) specgram = speclist.join(gap='ignore') try: # store median spectrum globalv.SPECTRUM[name] = specgram.percentile(50) except (ValueError, IndexError): unit = 'Mpc' if 'energy' in rangekwargs else 'Mpc^2 / Hz' globalv.SPECTRUM[name] = FrequencySeries( [], channel=channel, f0=0, df=1, unit=unit) globalv.SPECTRUM[cmin] = globalv.SPECTRUM[name] globalv.SPECTRUM[cmax] = globalv.SPECTRUM[name] else: # store percentiles globalv.SPECTRUM[cmin] = specgram.percentile(5) globalv.SPECTRUM[cmax] = specgram.percentile(95) if not return_: return if which == 'all': return (globalv.SPECTRUM[name], globalv.SPECTRUM[cmin], globalv.SPECTRUM[cmax]) if which == 'mean': return globalv.SPECTRUM[name] if which == 'min': return globalv.SPECTRUM[cmin] if which == 'max': return globalv.SPECTRUM[cmax] raise ValueError("Unrecognised value for `which`: %r" % which)
def vel2vel(fseries): #c2v = 10.0/2**15 #degain = 10**(-30./20.) z, p, k = trillium.zpk_120qa() num, den = zpk2tf(z, p, k) w, h = freqs(num, den, worN=np.logspace(-4, 5, 1e2)) mag = abs(h) f = w / np.pi / 2.0 func = interp1d(f, mag) _f = fseries.frequencies.value if False: plt.loglog(f, abs(mag), 'o-') #plt.loglog(_f,_mag) plt.savefig('hoge.png') vel2v = func(_f[1:]) value = fseries.value[1:] / vel2v * 1202.5 f0 = fseries.f0 df = fseries.df return FrequencySeries(value, df=df, f0=f0 + df)
def waveform(self, IFO=None, index=None, whiten=True): """ Generate waveform from a posterior sample INPUTS ------ IFO: str which instrument into which to project e.g. 'H1', 'L1' or 'V1' index: int which individual posterior sample to use? if None, then use the max posterior point whiten: bool if True, then whiten the signal RETURNS ------- model: the model waveform """ ind = self.MAPindex if index is None else ind dt = 1 / 2**np.ceil(np.log2(2 * max(self.f_high.values()))) # compute TD waveform model = self.samples.td_waveform(self.approx, dt, self.f_low[IFO], f_ref=self.f_ref, ind=ind, project=IFO) model.dx = dt if whiten: # unpack PSD into FrequencySeries ASD object fS = np.array(self.psd[IFO]) asd = FrequencySeries(np.sqrt(fS[:, 1]), frequencies=fS[:, 0]) # whiten the model model = model.whiten(asd=asd) return model
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
def test_read_ligolw(self): with tempfile.NamedTemporaryFile(mode='w+') as fobj: fobj.write(LIGO_LW_ARRAY) array = FrequencySeries.read( fobj, 'psd', match={'channel': 'X1:TEST-CHANNEL_1'}) utils.assert_array_equal(array, list(range(1, 11)) / units.Hz) utils.assert_array_equal(array.frequencies, list(range(10)) * units.Hz) assert numpy.isclose(array.epoch.gps, 1000000000) # precision gah! assert array.unit == units.Hz ** -1 array2 = FrequencySeries.read( fobj, 'psd', match={'channel': 'X1:TEST-CHANNEL_2'}) assert array2.epoch is None # assert errors with pytest.raises(ValueError): FrequencySeries.read(fobj, 'blah') with pytest.raises(ValueError): FrequencySeries.read(fobj, 'psd') with pytest.raises(ValueError): FrequencySeries.read( fobj, 'psd', match={'channel': 'X1:TEST-CHANNEL_1', 'blah': 'blah'})
def plot(request): # if this is a POST request we need to process the form data if request.method == 'GET': # create a form instance and populate it with data from the request: form = WaveformForm(request.GET) # check whether it's valid: if form.is_valid(): # This is where waveform generation code will go Chris P # You parse the request for as such f, hp, hx = gen_waveform(form.cleaned_data) assert len(f) == len(hp), "{0}, {1}".format(len(f), len(hp)) hp = FrequencySeries(hp, frequencies=f) hx = FrequencySeries(hx, frequencies=f) asd = FrequencySeries( gen_psd(form, f), frequencies=f) if form.cleaned_data["psd"] != "None" else None plot = hp.abs().plot(color='red', label=r"$|h_+|(f)$", yscale='log') ax = plot.gca() ax.plot(hx.abs(), color='black', linestyle='-.', label=r"$|h_x|(f)$") if asd is not None: ax.plot(asd) # For now just plot |h| # FIXME: These will most likely overlap ax.set_ylabel(r'GW strain [strain$/\sqrt{\mathrm{Hz}}$]') plot.legend() buf = io.BytesIO() canvas = FigureCanvas(plot) canvas.print_png(buf) response = HttpResponse(buf.getvalue(), content_type='image/png') pyplot.close(plot) return response
def draw(self): # initialise (plot, axes) = self.init_plot() ax = axes[0] ax.grid(b=True, axis='y', which='major') channel = self.channels[0] # parse data arguments sdform = self.pargs.pop('format') clim = self.pargs.pop('clim') clog = self.pargs.pop('logcolor') clabel = self.pargs.pop('colorlabel') rasterized = self.pargs.pop('rasterized', True) ratio = self.ratio # get cmap if ratio in ['median', 'mean'] or ( isinstance(ratio, str) and os.path.isfile(ratio)): self.pargs.setdefault('cmap', 'Spectral_r') cmap = self.pargs.pop('cmap', None) # get data if self.state and not self.all_data: valid = self.state.active else: valid = SegmentList([self.span]) if self.type == 'coherence-spectrogram': specgrams = get_coherence_spectrogram(self.channels, valid, query=False) else: specgrams = get_spectrogram(channel, valid, query=False, format=sdform) # calculate ratio spectrum if len(specgrams) and (ratio in ['median', 'mean'] or isinstance(ratio, int)): try: allspec = specgrams.join(gap='ignore') except ValueError as e: if 'units do not match' in str(e): warnings.warn(str(e)) for spec in specgrams[1:]: spec.unit = specgrams[0].unit allspec = specgrams.join(gap='ignore') else: raise if isinstance(ratio, int): ratio = allspec.percentile(ratio) else: ratio = getattr(allspec, ratio)(axis=0) elif isinstance(ratio, str) and os.path.isfile(ratio): try: ratio = FrequencySeries.read(ratio) except IOError as e: warnings.warn('IOError: %s' % str(e)) except Exception as e: # hack for old versions of GWpy # TODO: remove me when GWSumm requires GWpy > 0.1 if 'Format could not be identified' in str(e): ratio = FrequencySeries.read(ratio, format='dat') else: raise # allow channel data to set parameters if getattr(channel, 'frequency_range', None) is not None: self.pargs.setdefault('ylim', channel.frequency_range) if isinstance(self.pargs['ylim'], Quantity): self.pargs['ylim'] = self.pargs['ylim'].value if (ratio is None and sdform in ['amplitude', 'asd'] and hasattr(channel, 'asd_range') and clim is None): clim = channel.asd_range elif (ratio is None and hasattr(channel, 'psd_range') and clim is None): clim = channel.psd_range # plot data for specgram in specgrams: # undo demodulation specgram = undo_demodulation(specgram, channel, self.pargs.get('ylim', None)) # calculate ratio if ratio is not None: specgram = specgram.ratio(ratio) # plot ax.plot_spectrogram(specgram, cmap=cmap, rasterized=rasterized) # add colorbar if len(specgrams) == 0: ax.scatter([1], [1], c=[1], visible=False, cmap=cmap) plot.add_colorbar(ax=ax, clim=clim, log=clog, label=clabel, cmap=cmap) # customise and finalise for key, val in self.pargs.iteritems(): if key == 'ratio': continue try: getattr(ax, 'set_%s' % key)(val) except AttributeError: setattr(ax, key, val) if self.state: self.add_state_segments(ax) return self.finalize()
def _draw(self): """Load all data, and generate this `SpectrumDataPlot` """ plot = self.plot = FrequencySeriesPlot( figsize=self.pargs.pop('figsize', [12, 6])) ax = plot.gca() ax.grid(b=True, axis='both', which='both') if self.state: self.pargs.setdefault( 'suptitle', '[%s-%s, state: %s]' % (self.span[0], self.span[1], label_to_latex(str(self.state)))) suptitle = self.pargs.pop('suptitle', None) if suptitle: plot.suptitle(suptitle, y=0.993, va='top') # get spectrum format: 'amplitude' or 'power' sdform = self.pargs.pop('format') if sdform == 'rayleigh': method = 'rayleigh' else: method = None use_percentiles = str( self.pargs.pop('no-percentiles')).lower() == 'false' # parse plotting arguments plotargs = self.parse_plot_kwargs() legendargs = self.parse_legend_kwargs() # get reference arguments refs = [] refkey = 'None' for key in sorted(self.pargs.keys()): if key == 'reference' or re.match('reference\d+\Z', key): refs.append(dict()) refs[-1]['source'] = self.pargs.pop(key) refkey = key if re.match('%s[-_]' % refkey, key): refs[-1][key[len(refkey)+1:]] = self.pargs.pop(key) # add data if self.type == 'coherence-spectrum': iterator = zip(self.channels[0::2], self.channels[1::2], plotargs) else: iterator = zip(self.channels, plotargs) for chantuple in iterator: channel = chantuple[0] channel2 = chantuple[1] pargs = chantuple[-1] if self.state and not self.all_data: valid = self.state else: valid = SegmentList([self.span]) if self.type == 'coherence-spectrum': data = get_coherence_spectrum([str(channel), str(channel2)], valid, query=False) else: data = get_spectrum(str(channel), valid, query=False, format=sdform, method=method) # undo demodulation for spec in data: spec = undo_demodulation(spec, channel, self.pargs.get('xlim', None)) # anticipate log problems if self.pargs['logx']: data = [s[1:] for s in data] if self.pargs['logy']: for sp in data: sp.value[sp.value == 0] = 1e-100 if use_percentiles: ax.plot_spectrum_mmm(*data, **pargs) else: pargs.pop('alpha', None) ax.plot_spectrum(data[0], **pargs) # allow channel data to set parameters if getattr(channel, 'frequency_range', None) is not None: self.pargs.setdefault('xlim', channel.frequency_range) if isinstance(self.pargs['xlim'], Quantity): self.pargs['xlim'] = self.pargs['xlim'].value if (sdform in ['amplitude', 'asd'] and hasattr(channel, 'asd_range')): self.pargs.setdefault('ylim', channel.asd_range) elif hasattr(channel, 'psd_range'): self.pargs.setdefault('ylim', channel.psd_range) # display references for i, ref in enumerate(refs): if 'source' in ref: source = ref.pop('source') try: refspec = FrequencySeries.read(source) except IOError as e: warnings.warn('IOError: %s' % str(e)) except Exception as e: # hack for old versions of GWpy # TODO: remove me when GWSumm requires GWpy > 0.1 if 'Format could not be identified' in str(e): refspec = FrequencySeries.read(source, format='dat') else: raise else: ref.setdefault('zorder', -len(refs) + 1) if 'filter' in ref: refspec = refspec.filter(*ref.pop('filter')) if 'scale' in ref: refspec *= ref.pop('scale', 1) ax.plot(refspec, **ref) # customise hlines = list(self.pargs.pop('hline', [])) for key, val in self.pargs.iteritems(): try: getattr(ax, 'set_%s' % key)(val) except AttributeError: setattr(ax, key, val) # add horizontal lines to add if hlines: if not isinstance(hlines[-1], float): lineparams = hlines.pop(-1) else: lineparams = {'color':'r', 'linestyle': '--'} for yval in hlines: try: yval = float(yval) except ValueError: continue else: ax.plot(ax.get_xlim(), [yval, yval], **lineparams) if len(self.channels) > 1 or ax.legend_ is not None: plot.add_legend(ax=ax, **legendargs) if not plot.colorbars: plot.add_colorbar(ax=ax, visible=False) return self.finalize()
def _draw(self): """Load all data, and generate this `SpectrumDataPlot` """ plot = self.plot = FrequencySeriesPlot( figsize=self.pargs.pop('figsize', [12, 6])) ax = plot.gca() if self.state: self.pargs.setdefault( 'suptitle', '[%s-%s, state: %s]' % (self.span[0], self.span[1], label_to_latex(str(self.state)))) suptitle = self.pargs.pop('suptitle', None) if suptitle: plot.suptitle(suptitle, y=0.993, va='top') # parse plotting arguments cmap = self.pargs.pop('cmap', None) varargs = self.parse_variance_kwargs() plotargs = self.parse_plot_kwargs()[0] legendargs = self.parse_legend_kwargs() # get reference arguments refs = [] refkey = 'None' for key in sorted(self.pargs.keys()): if key == 'reference' or re.match('reference\d+\Z', key): refs.append(dict()) refs[-1]['source'] = self.pargs.pop(key) refkey = key if re.match('%s[-_]' % refkey, key): refs[-1][key[len(refkey)+1:]] = self.pargs.pop(key) # get channel arguments if hasattr(self.channels[0], 'asd_range'): low, high = self.channels[0].asd_range varargs.setdefault('low', low) varargs.setdefault('high', high) # calculate spectral variance and plot # pad data request to over-fill plots (no gaps at the end) if self.state and not self.all_data: valid = self.state.active else: valid = SegmentList([self.span]) livetime = float(abs(valid)) if livetime: plotargs.setdefault('vmin', 1/livetime) plotargs.setdefault('vmax', 1.) plotargs.pop('label') specgram = get_spectrogram(self.channels[0], valid, query=False, format='asd').join(gap='ignore') if specgram.size: asd = specgram.median(axis=0) asd.name = None variance = specgram.variance(**varargs) # normalize the variance variance /= livetime / specgram.dt.value # undo demodulation variance = undo_demodulation(variance, self.channels[0], self.pargs.get('xlim', None)) # plot ax.plot(asd, color='grey', linewidth=0.3) m = ax.plot_variance(variance, cmap=cmap, **plotargs) #else: # ax.scatter([1], [1], c=[1], visible=False, vmin=plotargs['vmin'], # vmax=plotargs['vmax'], cmap=plotargs['cmap']) #plot.add_colorbar(ax=ax, log=True, label='Fractional time at amplitude') # allow channel data to set parameters if getattr(self.channels[0], 'frequency_range', None) is not None: self.pargs.setdefault('xlim', self.channels[0].frequency_range) if isinstance(self.pargs['xlim'], Quantity): self.pargs['xlim'] = self.pargs['xlim'].value if hasattr(self.channels[0], 'asd_range'): self.pargs.setdefault('ylim', self.channels[0].asd_range) # display references for i, ref in enumerate(refs): if 'source' in ref: source = ref.pop('source') try: refspec = FrequencySeries.read(source) except IOError as e: warnings.warn('IOError: %s' % str(e)) except Exception as e: # hack for old versions of GWpy # TODO: remove me when GWSumm requires GWpy > 0.1 if 'Format could not be identified' in str(e): refspec = FrequencySeries.read(source, format='dat') else: raise else: if 'filter' in ref: refspec = refspec.filter(*ref.pop('filter')) if 'scale' in ref: refspec *= ref.pop('scale', 1) ax.plot(refspec, **ref) # customise hlines = list(self.pargs.pop('hline', [])) self.apply_parameters(ax, **self.pargs) # add horizontal lines to add if hlines: if not isinstance(hlines[-1], float): lineparams = hlines.pop(-1) else: lineparams = {'color':'r', 'linestyle': '--'} for yval in hlines: try: yval = float(yval) except ValueError: continue else: ax.plot(ax.get_xlim(), [yval, yval], **lineparams) # set grid ax.grid(b=True, axis='both', which='both') if not plot.colorbars: plot.add_colorbar(ax=ax, visible=False) return self.finalize()