def main_compare_gif_gotic2(): start = tconvert('Oct 15 2018 00:00:00') end = tconvert('Oct 21 2018 00:00:00') # gif data pfx = '/Users/miyo/Dropbox/KagraData/gif/' segments = GifData.findfiles(start, end, 'CALC_STRAIN', prefix=pfx) allfiles = [path for files in segments for path in files] strain = TimeSeries.read(source=allfiles, name='CALC_STRAIN', format='gif', pad=numpy.nan, nproc=2) strain = strain.detrend('linear') # gotic data source = '201805010000_201811010000.gotic' gifx = KagraGoticStrain.read(source, start=start, end=end).x gifx = gifx.detrend('linear') gifx = gifx * 0.9 # plot plot = Plot(gifx, strain, xscale='auto-gps') plot.legend() plot.subplots_adjust(right=.86) plot.savefig('result.png') plot.close()
def test_save_legend(tmpdir): base = str(tmpdir) fig = Plot() ax = fig.gca() ax.plot(SERIES, label=SERIES.name) tsplot = plot.save_legend(ax, os.path.join(base, 'test.png')) assert tsplot == os.path.join(base, 'test.png') shutil.rmtree(base, ignore_errors=True)
def test_apply_parameters(self, plot): fig = Plot() ax = fig.gca() plot.apply_parameters(ax, **{ 'xlim': (10, 20), 'no-blah': 'anything', 'grid': False, }) assert ax.get_xlim() == (10, 20)
def test_apply_parameters(self, plot): fig = Plot() ax = fig.gca() plot.apply_parameters(ax, **{ 'xlim': (10, 20), 'no-blah': 'anything', 'grid': False, }) assert ax.get_xlim() == (10, 20)
def hveto_roc(outfile, rounds, figsize=[9, 6], constants=[1, 5, 10, 20], **kwargs): efficiency = [] deadtime = [] for r in rounds: try: efficiency.append(r.cum_efficiency[0] / r.cum_efficiency[1]) except ZeroDivisionError: efficiency.append(0.) try: deadtime.append(r.cum_deadtime[0] / r.cum_deadtime[1]) except ZeroDivisionError: deadtime.append(0.) plot = Plot(figsize=figsize) ax = plot.gca() ax.plot(deadtime, efficiency, marker='o', linestyle='-') try: xbound = 10**floor(log10(deadtime[0])) except ValueError: xbound = 1e-4 try: ybound = 10**floor(log10(efficiency[0])) except ValueError: ybound = 1e-4 bound = min(xbound, ybound) axargs = { 'xlabel': 'Fractional deadtime', 'ylabel': 'Fractional efficiency', 'xscale': 'log', 'yscale': 'log', 'xlim': (bound, 1.), 'ylim': (bound, 1.), } axargs.update(kwargs) # draw some eff/dt contours if len(constants): for i, c in enumerate(constants): g = 1 - ((i + 1) / len(constants) * .5) x = axargs['xlim'] y = [a * c for a in x] ax.plot(x, y, linestyle='--', color=(g, g, g), label=str(c)) ax.legend(title='Eff/dt:', borderaxespad=0, bbox_to_anchor=(1.01, 1), handlelength=1, handletextpad=.5, loc='upper left') # save and close _finalize_plot(plot, ax, outfile, **axargs)
def save_legend(axes, pngfile, loc='center', frameon=False, fontsize='small', **kwargs): """Save a figure with a legend """ fig = Plot() leg = fig.legend(*axes.get_legend_handles_labels(), loc=loc, frameon=frameon, fontsize=fontsize, **kwargs) for line in leg.get_lines(): line.set_linewidth(8) fig.canvas.draw_idle() return save_figure(fig, pngfile, bbox_inches=(leg.get_window_extent().transformed( fig.dpi_scale_trans.inverted())))
def spectral_comparison(gps, qspecgram, fringe, output, thresh=15, multipliers=(1, 2, 4, 8), colormap='viridis', figsize=[12, 8]): """Compare a high-resolution spectrogram with projected fringe frequencies Parameters ---------- gps : `float` reference GPS time (in seconds) to serve as the origin qspecgram : `~gwpy.spectrogram.Spectrogram` an interpolated high-resolution spectrogram fringe : `~gwpy.timeseries.TimeSeries` projected fringe frequencies (in Hz) output : `str` name of the output file thresh : `float`, optional frequency threshold (Hz) for scattering fringes, default: 15 multipliers : `tuple`, optional collection of fringe harmonic numbers to plot, can be given in any order, default: `(1, 2, 4, 8)` colormap : `str`, optional matplotlib colormap to use, default: viridis figsize : `tuple`, optional size (width x height) of the final figure, default: `(12, 8)` """ plot = Plot(figsize=figsize) # format spectral plot ax1 = plot.add_subplot(211) ax1.set_title('{0} at {1:.2f} with $Q$ of {2:.1f}'.format( qspecgram.name, gps, qspecgram.q)) _format_spectrogram(ax1, qspecgram, colormap=colormap) ax1.set_xlabel(None) # format fringe frequency plot ax2 = plot.add_subplot(212, sharex=ax1) ax2.set_title('{} scattering fringes'.format(fringe.name)) _format_timeseries(ax2, gps, fringe, multipliers=multipliers, thresh=thresh) # format timeseries axes ax2.set_ylim([-1, 60]) ax2.set_ylabel('Projected Frequency [Hz]') # save plot and close plot.savefig(output, bbox_inches='tight') plot.close()
def before_after_histogram(outfile, x, y, label1='Before', label2='After', bins=100, histtype='stepfilled', range=None, figsize=[9, 6], **kwargs): """Plot a histogram of SNR for two event distributions """ # format axis arguments axargs = { 'xscale': 'log', 'xlabel': 'Loudness', 'yscale': 'log', 'ylabel': 'Number of events', } axargs.update(kwargs) # create figure plot = Plot(figsize=figsize) ax = plot.gca() # make histogram if range is None: range = min(map(numpy.min, (x, y))), max(map(numpy.max, (x, y))) axargs.setdefault('xlim', range) histargs = { 'range': range, 'histtype': histtype, 'bins': bins, 'linewidth': 2, 'logbins': axargs['xscale'] == 'log', 'alpha': .8, } ax.hist(x, label=label1, facecolor='red', edgecolor='darkred', **histargs) ax.hist(y, label=label2, facecolor='dodgerblue', edgecolor='blue', **histargs) # add legend ax.legend(loc='upper right') # format axes axargs.setdefault('ylim', (.5, ax.yaxis.get_data_interval()[1] * 1.05)) _finalize_plot(plot, ax, outfile, **axargs)
def hveto_roc(outfile, rounds, figsize=[9, 6], constants=[1, 5, 10, 20], **kwargs): efficiency = [] deadtime = [] for r in rounds: try: efficiency.append(r.cum_efficiency[0] / r.cum_efficiency[1]) except ZeroDivisionError: efficiency.append(0.) try: deadtime.append(r.cum_deadtime[0] / r.cum_deadtime[1]) except ZeroDivisionError: deadtime.append(0.) plot = Plot(figsize=figsize) ax = plot.gca() ax.plot(deadtime, efficiency, marker='o', linestyle='-') try: xbound = 10 ** floor(log10(deadtime[0])) except ValueError: xbound = 1e-4 try: ybound = 10 ** floor(log10(efficiency[0])) except ValueError: ybound = 1e-4 bound = min(xbound, ybound) axargs = { 'xlabel': 'Fractional deadtime', 'ylabel': 'Fractional efficiency', 'xscale': 'log', 'yscale': 'log', 'xlim': (bound, 1.), 'ylim': (bound, 1.), } axargs.update(kwargs) # draw some eff/dt contours if len(constants): for i, c in enumerate(constants): g = 1 - ((i+1)/len(constants) * .5) x = axargs['xlim'] y = [a * c for a in x] ax.plot(x, y, linestyle='--', color=(g, g, g), label=str(c)) ax.legend(title='Eff/dt:', borderaxespad=0, bbox_to_anchor=(1.01, 1), handlelength=1, handletextpad=.5, loc='upper left') # save and close _finalize_plot(plot, ax, outfile, **axargs)
def make_omegascan(ifo, t0, durs): """Helper function to create a single omegascan image, with multiple durations. Parameters ---------- ifo : str 'H1', 'L1', or 'V1' t0 : int or float Central time of the omegascan. durs : list of floats/ints List of three durations which will be scanned symmetrically about t0. Example: [0.5, 2, 10] Returns ------- bytes or None bytes of png of the omegascan, or None if no omegascan created. """ # Explicitly use a non-interactive Matplotlib backend. plt.switch_backend('agg') # Collect data longest = max(durs) long_start, long_end = t0 - longest, t0 + longest cache = create_cache(ifo, long_start, long_end) strain_name = app.conf['strain_channel_names'][ifo] try: ts = TimeSeries.read(cache, strain_name, start=long_start, end=long_end).astype('float64') # Do q_transforms for the different durations qgrams = [ts.q_transform( frange=(20, 4096), gps=t0, outseg=(t0 - dur, t0 + dur), logf=True) for dur in durs] except (IndexError, FloatingPointError, ValueError): # data from cache can't be properly read, or data is weird fig = plt.figure() plt.axis("off") plt.text(0.1, 0.45, f"Failed to create {ifo} omegascan", fontsize=17) else: fig = Plot(*qgrams, figsize=(10 * len(durs), 5), geometry=(1, len(durs)), yscale='log', method='pcolormesh') for ax in fig.axes: fig.colorbar(ax=ax, label='Normalized energy', clim=(0, 30)) ax.set_epoch(t0) fig.suptitle(f'Omegascans of {strain_name} at {t0}', fontweight="bold") outfile = io.BytesIO() fig.savefig(outfile, format='png', dpi=300) return outfile.getvalue()
def plot_asd(data,replot=False,fftlength=2**7,show=False,**kwargs): if isinstance(data,TimeSeries): chname = data.name psd_specgram = data.spectrogram2(fftlength=fftlength, overlap=fftlength/2.0, window='hanning') elif isinstance(data,Spectrogram): chname = data.name specgram = data pngfname = to_pngfname(chname,ftype='ASD',**kwargs) if not replot and os.path.exists(pngfname): print('Skip plot {0}'.format(pngfname)) return None median = specgram.percentile(50) low = specgram.percentile(5) high = specgram.percentile(95) median = vel2vel(median) low = vel2vel(low) high = vel2vel(high) _f, _selfnoise = trillium.selfnoise(trillium='120QA',psd='ASD',unit='velo') _selfnoise = _selfnoise*1e6 plot = Plot() ax = plot.gca(xscale='log', xlim=(1e-3, 3e2), xlabel='Frequency [Hz]', #yscale='log', ylim=(1e-11, 3e-6), yscale='log', ylim=(1e-5, 3e-0), ylabel=r'Velocity [m/sec/\rtHz]') ax.plot(_f,_selfnoise,'-',linewidth=1,color='gray') ax.plot_mmm(median, low, high, color='gwpy:ligo-livingston') ax.set_title(chname.replace('_',' '),fontsize=16) ax.legend(labels=['Selfnoise','Measurement']) plot.savefig(pngfname) print('plot in ',pngfname) return plot
def before_after_histogram( outfile, x, y, label1='Before', label2='After', bins=100, histtype='stepfilled', range=None, figsize=[9, 6], **kwargs): """Plot a histogram of SNR for two event distributions """ # format axis arguments axargs = { 'xscale': 'log', 'xlabel': 'Loudness', 'yscale': 'log', 'ylabel': 'Number of events', } axargs.update(kwargs) # create figure plot = Plot(figsize=figsize) ax = plot.gca() # make histogram if range is None: range = min(map(numpy.min, (x, y))), max(map(numpy.max, (x, y))) axargs.setdefault('xlim', range) histargs = { 'range': range, 'histtype': histtype, 'bins': bins, 'linewidth': 2, 'logbins': axargs['xscale'] == 'log', 'alpha': .8, } ax.hist(x, label=label1, facecolor='red', edgecolor='darkred', **histargs) ax.hist(y, label=label2, facecolor='dodgerblue', edgecolor='blue', **histargs) # add legend ax.legend(loc='upper right') # format axes axargs.setdefault('ylim', (.5, ax.yaxis.get_data_interval()[1] * 1.05)) _finalize_plot(plot, ax, outfile, **axargs)
def spectral_comparison(gps, qspecgram, fringe, output, thresh=15, multipliers=(1, 2, 4, 8), colormap='viridis', figsize=[12, 8]): """Compare a high-resolution spectrogram with projected fringe frequencies Parameters ---------- gps : `float` reference GPS time (in seconds) to serve as the origin qspecgram : `~gwpy.spectrogram.Spectrogram` an interpolated high-resolution spectrogram fringe : `~gwpy.timeseries.TimeSeries` projected fringe frequencies (in Hz) output : `str` name of the output file thresh : `float`, optional frequency threshold (Hz) for scattering fringes, default: 15 multipliers : `tuple`, optional collection of fringe harmonic numbers to plot, can be given in any order, default: `(1, 2, 4, 8)` colormap : `str`, optional matplotlib colormap to use, default: viridis figsize : `tuple`, optional size (width x height) of the final figure, default: `(12, 8)` """ plot = Plot(figsize=figsize) # format spectral plot ax1 = plot.add_subplot(211) ax1.set_title('{0} at {1:.2f} with $Q$ of {2:.1f}'.format( qspecgram.name, gps, qspecgram.q)) _format_spectrogram(ax1, qspecgram, colormap=colormap) ax1.set_xlabel(None) # format fringe frequency plot ax2 = plot.add_subplot(212, sharex=ax1) ax2.set_title('{} scattering fringes'.format(fringe.name)) _format_timeseries(ax2, gps, fringe, multipliers=multipliers, thresh=thresh) # format timeseries axes ax2.set_ylim([-1, 60]) ax2.set_ylabel('Projected Frequency [Hz]') # save plot and close plot.savefig(output, bbox_inches='tight') plot.close()
def spectral_overlay(gps, qspecgram, fringe, output, multipliers=(1, 2, 4, 8), figsize=[12, 4]): """Overlay scattering fringe projections on top of a high-resolution spectrogram Parameters ---------- gps : `float` reference GPS time (in seconds) to serve as the origin qspecgram : `~gwpy.spectrogram.Spectrogram` an interpolated high-resolution spectrogram fringe : `~gwpy.timeseries.TimeSeries` projected fringe frequencies (in Hz) output : `str` name of the output file multipliers : `tuple`, optional collection of fringe harmonic numbers to plot, can be given in any order, default: `(1, 2, 4, 8)` figsize : `tuple`, optional size (width x height) of the final figure, default: `(12, 4)` """ plot = Plot(figsize=figsize) ax = plot.gca() # format spectrogram plot ax.set_title('Fringes: {0}, Spectrogram: {1}'.format( fringe.name, qspecgram.name)) _format_spectrogram(ax, qspecgram, colormap='binary') # overlay fringe frequencies _format_timeseries(ax, gps, fringe, multipliers=multipliers, linewidth=1.5) ax.set_ylim([ qspecgram.f0.to('Hz').value, qspecgram.frequencies.max().to('Hz').value ]) # save plot and close plot.savefig(output, bbox_inches='tight') plot.close()
def spectral_overlay(gps, qspecgram, fringe, output, multipliers=(1, 2, 4, 8), figsize=[12, 4]): """Overlay scattering fringe projections on top of a high-resolution spectrogram Parameters ---------- gps : `float` reference GPS time (in seconds) to serve as the origin qspecgram : `~gwpy.spectrogram.Spectrogram` an interpolated high-resolution spectrogram fringe : `~gwpy.timeseries.TimeSeries` projected fringe frequencies (in Hz) output : `str` name of the output file multipliers : `tuple`, optional collection of fringe harmonic numbers to plot, can be given in any order, default: `(1, 2, 4, 8)` figsize : `tuple`, optional size (width x height) of the final figure, default: `(12, 4)` """ plot = Plot(figsize=figsize) ax = plot.gca() # format spectrogram plot ax.set_title('Fringes: {0}, Spectrogram: {1}'.format( fringe.name, qspecgram.name)) _format_spectrogram(ax, qspecgram, colormap='binary') # overlay fringe frequencies _format_timeseries(ax, gps, fringe, multipliers=multipliers, linewidth=1.5) ax.set_ylim([qspecgram.f0.to('Hz').value, qspecgram.frequencies.max().to('Hz').value]) # save plot and close plot.savefig(output, bbox_inches='tight') plot.close()
def veto_scatter( outfile, a, b, label1='All', label2='Vetoed', x='time', y='snr', color=None, clim=None, clabel=None, cmap=None, clog=True, figsize=[9, 6],**kwargs): """Plot an x-y scatter of all/vetoed events """ # format axis arguments axargs = { 'yscale': 'log', 'ylabel': 'Loudness', } axargs['xscale'] = 'auto-gps' if x == 'time' else 'log' if isinstance(y, (list, tuple)): ya = y[0] yb = y[1] else: ya = yb = y axargs.update(kwargs) # create figure plot = Plot(figsize=figsize) ax = plot.gca() # add data if color is None: ax.scatter(a[x], a[ya], color='black', marker='o', label=label1, s=40) else: colorargs = {'edgecolor': 'none'} if clim: colorargs['vmin'] = clim[0] colorargs['vmax'] = clim[1] if clog: colorargs['norm'] = LogNorm(vmin=clim[0], vmax=clim[1]) a = a.copy() a.sort(color) m = ax.scatter(a[x], a[ya], c=a[color], label=label1, **colorargs) # add colorbar ax.colorbar(mappable=m, cmap=cmap, label=clabel) if isinstance(b, (list, tuple)) and len(b) == 2: # aux channel used/coinc (probably) colors = [{'color': c} for c in ( '#ffd200', # yellow '#d62728', # red )] elif isinstance(b, (list, tuple)): colors = list(rcParams['axes.prop_cycle']) else: b = [b] label2 = [label2] colors = [{'color': '#d62728'}] for i, data in enumerate(b): # setting the color here looks complicated, but is just a fancy # way of looping through the color cycle when scattering, but using # red if we only have one other data set ax.scatter(data[x], data[yb], marker='+', linewidth=1.5, label=label2[i], s=40, **colors[i % len(colors)]) # add legend if ax.get_legend_handles_labels()[0]: legargs = { 'loc': 'upper left', 'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0, 'numpoints': 1, 'scatterpoints': 1, 'handlelength': 1, 'handletextpad': .5 } legargs.update(dict( (x[7:], axargs.pop(x)) for x in list(axargs.keys()) if x.startswith('legend_') )) ax.legend(**legargs) # finalize for axis in ['x', 'y']: # get data limits lim = list(getattr(ax, '%saxis' % axis).get_data_interval()) # use given ybound lim[0] = axargs.get('%sbound' % axis, lim[0]) # scale out for visual lim[0] *= 0.95 lim[1] *= 1.05 # handle logs if axargs.get("%sscale" % axis, "linear") == "log" and lim[0] <= 0.: lim[0] = None axargs.setdefault('%slim' % axis, lim) _finalize_plot(plot, ax, outfile, **axargs)
from gwpy.plot import Plot plot = Plot() ax = plot.gca(xscale='log', xlim=(10, 1500), xlabel='Frequency [Hz]', yscale='log', ylim=(3e-24, 2e-20), ylabel=r'Strain noise [1/\rtHz]') ax.plot_mmm(median, low, high, color='gwpy:ligo-hanford') ax.set_title('LIGO-Hanford strain noise variation around GW170817', fontsize=16) plot.show()
from gwpy.plot import Plot plot = Plot(figsize=(12, 6)) ax = plot.gca() for specgram in spectrograms: ax.imshow(specgram) ax.set_xscale('auto-gps', epoch='Sep 16 2010') ax.set_xlim('Sep 16 2010', 'Sep 17 2010') ax.set_ylim(40, 2000) ax.set_yscale('log') ax.set_ylabel('Frequency [Hz]') ax.set_title('LIGO-Hanford strain data') ax.colorbar(cmap='viridis', norm='log', clim=(1e-23, 1e-19), label=r'Strain noise [1/\rtHz]') plot.add_segments_bar(h1segs) plot.show()
def diagnostic(soln, duration, npoints=1000, figsize=(12, 12), dpi=200): """Display figures-of-merit for accuracy and precision of a simulation This utility produces a figure with five subplots, showing the timeseries records of ``r``, number of cycles, total 3-velocity, and the fractional errors in total energy and specific angular momentum, all with respect to (unitless) proper time. Parameters ---------- soln : `~scipy.integrate.OdeSolution` interpolated solutions for ``r``, ``rdot``, and ``phi``, represented as a continuous function of proper time that returns an array of shape ``(3, n)`` duration : `float` duration (in unitless proper time) of the simulated orbit npoints : `int`, optional number of points to sample uniformly, default: 1000 .. note: This utility uses `~numpy.arange` with a step size of ``duration / npoints``, in contrast with the other tools in this module which use ``~numpy.linspace`` or ``~pyschild.utils.power_sample`` figsize : `tuple`, optional figure size in height x width (inches), default: ``(12, 12)`` dpi : `int`, optional figure resolution per square inch, default: 200 Returns ------- fig : `~matplotlib.pyplot.Figure` the populated figure object Examples -------- To get an extensive set of simulation figures-of-merit: >>> from pyschild.orbit import (timelike, plot) >>> y0 = timelike.initial_values(0.5) >>> (geodesic, duration) = timelike.simulate(y0, timelike.HISCO, tf=1000) >>> fig = plot.diagnostic(geodesic, duration) >>> fig.show() See also -------- pyschild.orbit.timelike.simulate the utility which numerically simulates massive particle orbits pyschild.orbit.timelike.velocity compute the total 3-velocity given ``r``, ``rdot``, and ``phidot`` """ dt = duration / npoints times = numpy.arange(0, duration, dt) (r, rdot, phi) = soln(times) phidot = numpy.gradient(phi, dt) beta = timelike.velocity(r, rdot, phidot) # get constants of the motion heval = phidot * r**2 geval = numpy.sqrt(rdot**2 + (1 + (heval / r)**2) * (1 - 2 / r)) # get `Signal` objects for each variable r = Signal(r, dt=dt) ncyc = Signal((phi - phi[0]) / (2 * numpy.pi), dt=dt) beta = Signal(timelike.velocity(r, rdot, phidot), dt=dt) herror = Signal(numpy.abs( (heval - heval[0]) / heval[0]) if heval[0] else numpy.abs(heval - heval[0]), dt=dt) gerror = Signal(numpy.abs( (geval - geval[0]) / geval[0]) if geval[0] else numpy.abs(geval - geval[0]), dt=dt) # construct a figure with five panels fig = Plot(r, ncyc, beta, gerror, herror, figsize=figsize, separate=True, sharex=False, sharey=False) ax = fig.axes for i in range(4): ax[i].set_xlabel('') ax[i].set_xticklabels([]) ax[i].grid(True, which='major', axis='both', alpha=0.4) ax[-1].set_xscale('seconds') ax[-1].set_xlabel(r'$c^3\tau/GM$') ax[0].plot((0, duration), (2, 2), color='#669999', linestyle='dashed') ax[0].set_ylabel('$c^2r/GM$') ax[0].set_ylim( (0 if r.min().value < 2 else 0.9 * r.min().value, 1.1 * r.max().value)) ax[1].set_ylabel('No. of cycles') ax[1].set_ylim((0, ncyc.max().value)) ax[2].set_ylabel(r'$\beta$') ax[2].set_ylim((0, max(1, beta.max().value))) ax[3].set_ylabel(r'$\gamma_{{\mathrm{{err}}}}$ rel. ' 'to {:.3g}'.format(geval[0])) gerr = gerror.value[~numpy.isnan(gerror.value)] ax[3].set_ylim((0.9 * gerr[1::].min(), min(gerr.max(), 1))) ax[3].set_yscale('log' if gerror[1::].value.min() else 'linear') ax[4].set_ylabel(r'$h_{{\mathrm{{err}}}}$ rel. ' 'to {:.3g}'.format(heval[0])) herr = herror.value[~numpy.isnan(herror.value)] ax[4].set_ylim((0.9 * herr[1::].min(), min(herr.max(), 1))) ax[4].set_yscale('log' if herror[1::].value.min() else 'linear') fig.tight_layout() return fig
# and then applying our de-whitening filter in `ZPK <TimeSeries.zpk>` format # with five zeros at 100 Hz and five poles at 1 Hz (giving an overall DC # gain of 10 :sup:`-10`: hp = white.highpass(4) displacement = hp.zpk([100]*5, [1]*5, 1e-10) # We can visualise the impact of the whitening by calculating the ASD # `~gwpy.frequencyseries.FrequencySeries` before and after the filter, whiteasd = white.asd(8, 4) dispasd = displacement.asd(8, 4) # and plotting: from gwpy.plot import Plot plot = Plot(whiteasd, dispasd, separate=True, sharex=True, xscale='log', yscale='log') # Here we have passed the two # `spectra <gwpy.frequencyseries.FrequencySeries>` in order, # then `separate=True` to display them on separate Axes, `sharex=True` to tie # the `~matplotlib.axis.XAxis` of each of the `~gwpy.plot.Axes` # together. # # Finally, we prettify our plot with some limits, and some labels: plot.text(0.95, 0.05, 'Preliminary', fontsize=40, color='gray', ha='right', rotation=45, va='bottom', alpha=0.5) # hide plot.axes[0].set_ylabel('ASD [whitened]') plot.axes[1].set_ylabel(r'ASD [m/$\sqrt{\mathrm{Hz}}$]') plot.axes[1].set_xlabel('Frequency [Hz]') plot.axes[1].set_ylim(1e-20, 1e-15) plot.axes[1].set_xlim(5, 4000) plot.show()
# # Now, we can loop through the active segments of ``'H1_DATA'`` and fetch the # strain `TimeSeries` for each segment, calculating a # :class:`~gwpy.spectrogram.Spectrogram` for each segment. from gwpy.timeseries import TimeSeries spectrograms = [] for start, end in h1segs.active: h1strain = TimeSeries.fetch_open_data('H1', start, end, verbose=True) specgram = h1strain.spectrogram(30, fftlength=4)**(1 / 2.) spectrograms.append(specgram) # Finally, we can build a :meth:`~gwpy.spectrogram.Spectrogram.plot`: from gwpy.plot import Plot plot = Plot(figsize=(12, 6)) ax = plot.gca() for specgram in spectrograms: ax.imshow(specgram) ax.set_xscale('auto-gps', epoch='Sep 16 2010') ax.set_xlim('Sep 16 2010', 'Sep 17 2010') ax.set_ylim(40, 2000) ax.set_yscale('log') ax.set_ylabel('Frequency [Hz]') ax.set_title('LIGO-Hanford strain data') ax.colorbar(cmap='viridis', norm='log', clim=(1e-23, 1e-19), label=r'Strain noise [1/\rtHz]') plot.add_segments_bar(h1segs) plot.show()
channels = [ '{ifo}:ISI-BS_ST1_SENSCOR_GND_STS_X_BLRMS_30M_100M.mean,s-trend', '{ifo}:ISI-BS_ST1_SENSCOR_GND_STS_Y_BLRMS_30M_100M.mean,s-trend', '{ifo}:ISI-BS_ST1_SENSCOR_GND_STS_Z_BLRMS_30M_100M.mean,s-trend', ] # At last we can :meth:`~TimeSeriesDict.get` 12 hours of data for each # interferometer: lho = TimeSeriesDict.get([c.format(ifo='H1') for c in channels], 'Feb 13 2015 16:00', 'Feb 14 2015 04:00') llo = TimeSeriesDict.get([c.format(ifo='L1') for c in channels], 'Feb 13 2015 16:00', 'Feb 14 2015 04:00') # Next we can plot the data, with a separate `~gwpy.plot.Axes` for each # instrument: plot = Plot(lho, llo, figsize=(12, 6), sharex=True, yscale='log') ax1, ax2 = plot.axes for ifo, ax in zip(('Hanford', 'Livingston'), (ax1, ax2)): ax.legend(['X', 'Y', 'Z']) ax.text(1.01, 0.5, ifo, ha='left', va='center', transform=ax.transAxes, fontsize=18) ax1.set_ylabel(r'$1-3$\,Hz motion [nm/s]', y=-0.1) ax2.set_ylabel('') ax1.set_title('Magnitude 7.1 earthquake impact on LIGO') plot.show()
from gwpy.plot import Plot plot = Plot() ax = plot.gca(xscale='log', xlim=(10, 1500), xlabel='Frequency [Hz]', yscale='log', ylim=(3e-24, 2e-20), ylabel=r'Strain noise [1/$\sqrt{\mathrm{Hz}}$]') ax.plot_mmm(median, low, high, color='gwpy:ligo-hanford') ax.set_title('LIGO-Hanford strain noise variation around GW170817', fontsize=16) plot.show()
def representative_spectra(channels, start, stop, rate, label='kmeans-labels', filename=DEFAULT_FILENAME, prefix='.', downloader=TimeSeriesDict.get, cluster_numbers=None, groups=None, **kwargs): """ Make representative spectra for each cluster based on the median psd for minutes in that cluster. Downloads only the raw minutes in the cluster to save. """ if groups is None: groups = channels # read the labels from the save file. labels = TimeSeries.read(filename, label, start=to_gps(start), end=to_gps(stop)) logger.info(f'Read labels {start} to {stop} from {filename}') if cluster_numbers is None: clusters = list(range(max(labels.value) + 1)) cluster_counts = list( len(labels.value[labels.value == c]) for c in clusters) largest_cluster = cluster_counts.index(max(cluster_counts)) clusters.remove(largest_cluster) logger.info( f'Largest cluster found to be Nº{largest_cluster} ({100 * max(cluster_counts) // len(labels.value)}%). Doing {clusters}.' ) cluster_counts.remove(max(cluster_counts)) else: clusters = cluster_numbers cluster_counts = list( len(labels.value[labels.value == c]) for c in clusters) t, v, d = labels.times, labels.value, diff(labels.value) pairs = list( zip([t[0]] + list(t[:-1][d != 0]), list(t[1:][d != 0]) + [t[-1]])) values = list(v[:-1][d != 0]) + [v[-1]] assert len(pairs) == len(values) # need to include start-| and |-end # l|r l|r l|r l|r # l,r l,r l,r l,r # l r,l r,l r,l r # zip(start + l[1:], r[:-1] + stop) print(pairs) for pair in pairs: print(int(pair[1].value) - int(pair[0].value)) print(values) # use h5py to make a mutable object pointing to a file on disk. save_file, filename = path2h5file( get_path(f'spectra-cache {start}', 'hdf5', prefix=prefix)) logger.debug(f'Initiated hdf5 stream to {filename}') logger.info(f'Patching {filename}...') for i, (dl_start, end) in enumerate(pairs): if values[i] in clusters: if not data_exists(channels, to_gps(end).seconds, save_file): logger.debug( f'Downloading Nº{values[i]} from {dl_start} to {end}...') try: dl = downloader(channels, start=to_gps(dl_start) - LIGOTimeGPS(60), end=to_gps(end) + LIGOTimeGPS(seconds=1)) out = TimeSeriesDict() for n in dl: out[n] = dl[n].resample(**better_aa_opts(dl[n], rate)) write_to_disk(out, to_gps(dl_start).seconds, save_file) except RuntimeError: # Cannot find all relevant data on any known server logger.warning( f"SKIPPING Nº{values[i]} from {dl_start} to {end} !!") logger.info('Reading data...') data = TimeSeriesDict.read(save_file, channels) logger.info('Starting PSD generation...') f = data[channels[0]].crop( start=to_gps(data[channels[0]].times[-1]) - LIGOTimeGPS(60), end=to_gps(data[channels[0]].times[-1])).psd().frequencies d = (to_gps(labels.times[-1]).seconds - to_gps(labels.times[1]).seconds) for i, cluster in enumerate(clusters): try: psds = { channel: FrequencySeries.read(filename, f'{cluster}-{channel}') for channel in channels } logger.info(f'Loaded Nº{cluster}.') except KeyError: logger.info( f'Doing Nº{cluster} ({100 * cluster_counts[i] / len(labels.value):.2f}% of data)...' ) with Progress(f'psd Nº{cluster} ({i + 1}/{len(clusters)})', len(channels) * d) as progress: psds = { channel: FrequencySeries(median(stack([ progress(data[channel].crop, pc * d + (to_gps(time).seconds - to_gps(labels.times[1]).seconds), start=to_gps(time) - LIGOTimeGPS(60), end=to_gps(time)).psd().value for c, time in zip(labels.value, labels.times) if c == cluster ]), axis=0), frequencies=f, name=f'{cluster}-{channel}') for pc, channel in enumerate(channels) } for name in psds.keys(): psds[name].write(filename, **writing_opts) # plotting is slow, so show a nice progress bar. logger.debug('Initiating plotting routine...') with Progress('plotting', len(groups)) as progress: for p, (group, lbls, title) in enumerate(groups): # plot the group in one figure. plt = Plot(*(psds[channel] for channel in group), separate=False, sharex=True, zorder=1, **kwargs) # plt.gca().set_xlim((30,60)) # modify the figure as a whole. # plt.add_segments_bar(dq, label='') plt.gca().set_xscale('log') plt.gca().set_yscale('log') plt.suptitle(title) plt.legend(lbls) # save to png. progress( plt.save, p, get_path(f'{cluster}-{title}', 'png', prefix=f'{prefix}/{cluster}'))
format='hdf5', overwrite=True, path='hoge') strain.write('./fs_gif.hdf5', format='hdf5', overwrite=True, path='hoge') # ----------------------------------------------- # Main # ----------------------------------------------- # ----------------------------------------------- # IXV1 DIFF12 # ----------------------------------------------- if comparison_ixv1_diff12: print('Comparison_IXV1_DIFF12') from gwpy.plot import Plot plot = Plot() ax = plot.gca(xscale='log', xlim=(1e-3, 100), yscale='log', ylim=(1e-7, 1e2)) ax.plot(ixv1, color='k', label='IXV1') ax.plot(diff12, color='r', label=r'(IXV1 - IXV2)/$\sqrt{2}$') ax.plot(tr120_selfnoise, color='k', label='Selfnoise', linestyle='--', zorder=0) ax.set_xlabel('Frequency [Hz]', fontsize=15) ax.set_ylabel(r'Displacement [um/$\sqrt{\mathrm{Hz}}$]', fontsize=15) ax.set_title('Trillium120QA Noise Investigation', fontsize=20) ax.text(110,
# We can now easily inject a loud sinusoid of unit amplitude at, say, # 30 Hz. To do this, we use :meth:`~gwpy.types.series.Series.inject`. import numpy from gwpy.frequencyseries import FrequencySeries signal = FrequencySeries(numpy.array([1.]), f0=30, df=noisefd.df) injfd = noisefd.inject(signal) # We can then visualize the data before and after injection in the frequency # domain: from gwpy.plot import Plot plot = Plot(numpy.abs(noisefd), numpy.abs(injfd), separate=True, sharex=True, sharey=True, xscale='log', yscale='log') plot.show() # Finally, for completeness we can visualize the effect before and after # injection back in the time domain: inj = injfd.ifft() plot = Plot(noise, inj, separate=True, sharex=True, sharey=True, figsize=(12, 6))
# Demodulation is useful when trying to examine steady sinusoidal # signals we know to be contained within data. For instance, # we can download some data from LOSC to look at trends of the # amplitude and phase of LIGO Livingston's calibration line at 331.3 Hz: from gwpy.timeseries import TimeSeries data = TimeSeries.fetch_open_data('L1', 1131350417, 1131357617) # We can demodulate the `TimeSeries` at 331.3 Hz with a stride of one # minute: amp, phase = data.demodulate(331.3, stride=60) # We can then plot these trends to visualize fluctuations in the # amplitude of the calibration line: from gwpy.plot import Plot plot = Plot(amp) ax = plot.gca() ax.set_ylabel('Strain Amplitude at 331.3 Hz') plot.show()
def significance_drop(outfile, old, new, show_channel_names=None, **kwargs): """Plot the signifiance drop for each channel """ channels = sorted(old.keys()) if show_channel_names is None: show_channel_names = len(channels) <= 50 plot = Plot(figsize=(18, 6)) plot.subplots_adjust(left=.07, right=.93) ax = plot.gca() if show_channel_names: plot.subplots_adjust(bottom=.4) winner = sorted(old.items(), key=lambda x: x[1])[-1][0] for i, c in enumerate(channels): if c == winner: color = 'orange' elif old[c] > new[c]: color = 'dodgerblue' else: color = 'red' ax.plot([i, i], [old[c], new[c]], color=color, linestyle='-', marker='o', markeredgecolor='k', markeredgewidth=.5, markersize=10, label=c, zorder=old[c]) ax.set_xlim(-1, len(channels)) ax.set_ybound(lower=0) # set xticks to show channel names if show_channel_names: ax.set_xticks(range(len(channels))) ax.set_xticklabels([c.replace('_','\_') for c in channels]) for i, t in enumerate(ax.get_xticklabels()): t.set_rotation(270) t.set_verticalalignment('top') t.set_horizontalalignment('center') t.set_fontsize(8) # or just show systems of channels else: plot.canvas.draw() systems = {} for i, c in enumerate(channels): sys = c.split(':', 1)[1].split('-')[0].split('_')[0] try: systems[sys][1] += 1 except KeyError: systems[sys] = [i, 1] systems = sorted(systems.items(), key=lambda x: x[1][0]) labels, counts = zip(*systems) xticks, xmticks = zip(*[(a, a+b/2.) for (a, b) in counts]) # show ticks at the edge of each group ax.set_xticks(xticks, minor=False) ax.set_xticklabels([], minor=False) # show label in the centre of each group ax.set_xticks(xmticks, minor=True) for t in ax.set_xticklabels(labels, minor=True): t.set_rotation(270) kwargs.setdefault('ylabel', 'Significance') # create interactivity if outfile.endswith('.svg'): _finalize_plot(plot, ax, outfile.replace('.svg', '.png'), close=False, **kwargs) tooltips = [] ylim = ax.get_ylim() yoffset = (ylim[1] - ylim[0]) * 0.061 bbox = {'fc': 'w', 'ec': '.5', 'alpha': .9, 'boxstyle': 'round'} xthresh = len(channels) / 10. for i, l in enumerate(ax.lines): x = l.get_xdata()[1] if x < xthresh: ha = 'left' elif x > (len(channels) - xthresh): ha ='right' else: ha = 'center' y = l.get_ydata()[0] + yoffset c = l.get_label() tooltips.append(ax.annotate(c.replace('_', r'\_'), (x, y), ha=ha, zorder=ylim[1], bbox=bbox)) l.set_gid('line-%d' % i) tooltips[-1].set_gid('tooltip-%d' % i) f = BytesIO() plot.savefig(f, format='svg') tree, xmlid = etree.XMLID(f.getvalue()) tree.set('onload', 'init(evt)') for i in range(len(tooltips)): try: e = xmlid['tooltip-%d' % i] except KeyError: warnings.warn("Failed to recover tooltip %d" % i) continue e.set('visibility', 'hidden') for i, l in enumerate(ax.lines): e = xmlid['line-%d' % i] e.set('onmouseover', 'ShowTooltip(this)') e.set('onmouseout', 'HideTooltip(this)') tree.insert(0, etree.XML(SHOW_HIDE_JAVASCRIPT)) etree.ElementTree(tree).write(outfile) plot.close() else: _finalize_plot(plot, ax, outfile, **kwargs)
from gwpy.plot import Plot plot = Plot(gwdata.asd(2, 1), rayleigh, geometry=(2, 1), sharex=True, xscale='log', xlim=(30, 1500)) asdax, rayax = plot.axes asdax.set_yscale('log') asdax.set_ylim(5e-24, 1e-21) asdax.set_ylabel(r'[strain/\rtHz]') rayax.set_ylim(0, 2) rayax.set_ylabel('Rayleigh statistic') asdax.set_title('Sensitivity of LIGO-Livingston around GW151226', fontsize=20) plot.show()
# To see the effect of the Planck-taper window, we can taper a # sinusoidal `TimeSeries` at both ends: import numpy from gwpy.timeseries import TimeSeries t = numpy.linspace(0, 1, 2048) series = TimeSeries(numpy.cos(10.5*numpy.pi*t), times=t) tapered = series.taper() # We can plot it to see how the ends now vary smoothly from 0 to 1: from gwpy.plot import Plot plot = Plot(series, tapered, separate=True, sharex=True) plot.show()
if len(pks) > 0: try: Max_Amp = 10**np.max(x[pks[(pks > 1200) & (pks < 4800)]]) Max_Amp_Loc = pks[np.argmax(x[pks[(pks > 1200) & (pks < 4800)]])] except: print("An exception occured, peak likely to be out of range") print("Max_Amp = {} nm/s, Max_Amp_Loc = {}".format(Max_Amp,Max_Amp_Loc)) print(' ') ########################### SAVE RESULTS ############################# if saveData: np.savetxt(fileName,dataX) print('Data saved to {}'.format(fileName) ) if saveImage: plot = Plot(DATA, figsize=(12, 6), sharex=True, yscale='log') ax1 = plot.axes for ifo, ax in zip(('Livingston'), (ax1)): ax.legend(['ITMY-X', 'ITMY-Y', 'ITMY-Z','ETMY-X', 'ETMY-Y', 'ETMY-Z','ETMX-X', 'ETMX-Y', 'ETMX-Z']) #ax.text(1.01, 0.5, ifo, ha='left', va='center', transform=ax.transAxes,fontsize=18) ax.set_ylabel('Ground motion [$ nm/s $]') ax.set_title('Magnitude {} earthquake: Impact on {}'.format(MAG,IFO)) plot.savefig(figName) print('Figure saved to {}'.format(figName) ) if saveResult: np.savetxt(resultName, (Max_Amp,Max_Amp_Loc)) print('Result saved to {}'.format(resultName) ) print("#########################################################")
def plot_timeseries(*data, **kwargs): title = kwargs.pop('title', None) ylim = kwargs.pop('ylim', None) fname = kwargs.pop('fname', 'TimeSeries.png') plot = Plot(figsize=(15, 10)) ax0 = plot.gca() ax0.plot(*data) ax0.legend([text.to_string(_data.name) for _data in data], fontsize=20) ax0.set_xscale('auto-gps') ax0.set_ylabel(text.to_string(data[0].unit)) plot.add_state_segments(segments_daq_iy0_ok, label='IY0 DAQ State') plot.add_state_segments(segments_daq_ix1_ok, label='IX1 DAQ State') plot.suptitle(title, fontsize=40) if ylim: ax0.set_ylim(ylim[0], ylim[1]) plot.savefig(fname) plot.close()
from gwpy.plot import Plot plot = Plot(l1hoft, h1hoft) plot.show()
# Then we can download a simulation of the GW150914 signal from LOSC: from astropy.utils.data import get_readable_fileobj source = 'https://losc.ligo.org/s/events/GW150914/P150914/' url = '%s/fig2-unfiltered-waveform-H.txt' % source with get_readable_fileobj(url) as f: signal = TimeSeries.read(f, format='txt') signal.t0 = .5 # make sure this intersects with noise time samples # Note, since this simulation cuts off before a certain time, it is # important to taper its ends to zero to avoid ringing artifacts. # We can accomplish this using the # :meth:`~gwpy.timeseries.TimeSeries.taper` method. signal = signal.taper() # Since the time samples overlap, we can inject this into our noise data # using :meth:`~gwpy.types.series.Series.inject`: data = noise.inject(signal) # Finally, we can visualize the full process in the time domain: from gwpy.plot import Plot plot = Plot(noise, signal, data, separate=True, sharex=True, sharey=True) plot.gca().set_epoch(0) plot.show() # We can clearly see that the loud GW150914-like signal has been layered # on top of Gaussian noise with the correct amplitude and phase evolution.
from gwpy.plot import Plot plot = Plot() ax = plot.gca(xscale='log', xlim=(10, 1500), xlabel='Frequency [Hz]', yscale='log', ylim=(3e-24, 2e-20), ylabel=r'Strain noise [1/$\sqrt{\mathrm{Hz}}$]') ax.plot_mmm(median, low, high, color='gwpy:ligo-hanford') ax.set_title('LIGO-Hanford strain noise variation around GW170817', fontsize=16) plot.show()
# method), the easiest application would be `TimeSeries.zpk` # The :mod:`~gwpy.signal.filter_design` methods return infinite impulse # response filters by default, which, when applied, corrupt a small amount of # data at the beginning and the end of our original `TimeSeries`. # We can discard those data using the :meth:`~TimeSeries.crop` method # (for consistency we apply this to both data series): hdata = hdata.crop(*hdata.span.contract(1)) hfilt = hfilt.crop(*hfilt.span.contract(1)) # Finally, we can :meth:`~TimeSeries.plot` the original and filtered data, # adding some code to prettify the figure: from gwpy.plot import Plot plot = Plot(hdata, hfilt, figsize=[12, 6], separate=True, sharex=True, color='gwpy:ligo-hanford') ax1, ax2 = plot.axes ax1.set_title('LIGO-Hanford strain data around GW150914') ax1.text(1.0, 1.01, 'Unfiltered data', transform=ax1.transAxes, ha='right') ax1.set_ylabel('Amplitude [strain]', y=-0.2) ax2.set_ylabel('') ax2.text(1.0, 1.01, '50-250\,Hz bandpass, notches at 60, 120, 180 Hz', transform=ax2.transAxes, ha='right') plot.show() plot.close() # hide # We see now a spike around 16 seconds into the data, so let's zoom into # that time (and prettify): plot = hfilt.plot(color='gwpy:ligo-hanford') ax = plot.gca()
# gain of 10 :sup:`-10`: hp = white.highpass(4) displacement = hp.zpk([100] * 5, [1] * 5, 1e-10) # We can visualise the impact of the whitening by calculating the ASD # `~gwpy.frequencyseries.FrequencySeries` before and after the filter, whiteasd = white.asd(8, 4) dispasd = displacement.asd(8, 4) # and plotting: from gwpy.plot import Plot plot = Plot(whiteasd, dispasd, separate=True, sharex=True, xscale='log', yscale='log') # Here we have passed the two # `spectra <gwpy.frequencyseries.FrequencySeries>` in order, # then `separate=True` to display them on separate Axes, `sharex=True` to tie # the `~matplotlib.axis.XAxis` of each of the `~gwpy.plot.Axes` # together. # # Finally, we prettify our plot with some limits, and some labels: plot.text(0.95, 0.05, 'Preliminary', fontsize=40, color='gray',
from gwpy.plot import Plot plot = Plot(figsize=(12, 4)) ax = plot.add_subplot(xscale='auto-gps') ax.plot(h1b, color='gwpy:ligo-hanford', label='LIGO-Hanford') ax.plot(l1b, color='gwpy:ligo-livingston', label='LIGO-Livingston') ax.set_epoch(1126259462.427) ax.set_xlim(1126259462.2, 1126259462.5) ax.set_ylim(-1e-21, 1e-21) ax.set_ylabel('Strain noise') ax.legend() plot.show()
def main(start, end, chname): data = TimeSeries.read(dumped_gwf_fmt.format(start=start, end=end, chname=channel), channel, verbose=True, nproc=8) # Filtering from gwpy.signal import filter_design from gwpy.plot import BodePlot import numpy bp_high = filter_design.highpass( 0.3, data.sample_rate, analog=True, ftype='butter', gpass=2, gstop=30 #,fstop() ) bp_mid = filter_design.bandpass( 0.05, 0.3, data.sample_rate, analog=True, ftype='butter', gpass=2, gstop=30 #,fstop=(0.01,0.5) ) bp_low = filter_design.lowpass( 0.05, data.sample_rate, analog=True, ftype='butter', gpass=2, gstop=30 #, fstop=2 ) filters = [bp_high, bp_mid, bp_low] plot = BodePlot(*filters, analog=True, frequencies=numpy.logspace(-3, 1, 1e5), dB=False, unwrap=False, title='filter') axes = plot.get_axes() axes[0].set_yscale('log') axes[0].set_ylim(1e-4, 2e0) axes[-1].set_xlim(1e-2, 1e0) axes[-1].set_ylim(-180, 180) plot.savefig('Bodeplot_BandPass.png') plot.close() data_high = data.filter(bp_high, filtfilt=True) data_high = data_high.crop(*data_high.span.contract(1)) data_mid = data.filter(bp_mid, filtfilt=True) data_mid = data_mid.crop(*data_mid.span.contract(1)) data_low = data.filter(bp_low, filtfilt=True) data_low = data_low.crop(*data_low.span.contract(1)) # Plot TimeSeries title = channel[3:].replace('_', ' ') labels = [ 'No filt', 'High (300mHz-)', 'Mid (50mHz-300mHz)', 'Low (-50mHz)' ] if data.unit == ' ': yaxis_label = 'Count' else: yaxis_label = data.unit from gwpy.plot import Plot data_set = [data, data_high, data_mid, data_low] plot = Plot(*data_set, separate=True, sharex=True, sharey=True, color='gwpy:ligo-livingston', figsize=[10, 10]) axes = plot.get_axes() for i, ax in enumerate(axes): ax.legend([labels[i]], loc='upper left') plot.text(0.04, 0.5, yaxis_label, va='center', rotation='vertical', fontsize=16) #plot.text(0.5, 0.93, title, va='center',ha='center',rotation='horizontal',fontsize=16) axes[0].set_title(title, fontsize=16) axes[-1].set_xscale('Hours', epoch=start) plot.savefig(timeseriesplot_fname_fmt.format(channel=channel)) plot.close()
_aanoise = FrequencySeries(_aanoise, frequencies=ref.frequencies) amp = 10**(30 / 20.) tr120q = Trillium('120QA') tr240 = Trillium('240') v2vel = tr120q.v2vel v2vel = tr240.v2vel adcnoise = v2vel(_adcnoise) / amp ampnoise = v2vel(_ampnoise) / amp # aanoise = v2vel(_aanoise) / amp selfnoise_120q = tr120q.selfnoise() selfnoise_240 = tr240.selfnoise() # Plot if True: from gwpy.plot import Plot plot = Plot() ax = plot.gca(xscale='log', xlim=(1e-3, 10), xlabel='Frequency [Hz]', yscale='log', ylim=(1e-12, 1e-4), ylabel=r'Velocity [m/sec/\rtHz]') #ax.loglog(x1500,label='x1500 (ref. GIF data)') ax.loglog(selfnoise_120q, 'k--', label='Self Noise 120Q', linewidth=1, alpha=0.7) ax.loglog(selfnoise_240, 'm--', label='Self Noise 240',
name=stat, sample_rate=float(sample_rate)) cutoff_low = 0.1 dataFull = dataFull.lowpass(frequency=cutoff_low) return dataFull # start = [2019, 11, 20, 2, 0, 0, 0] # end = [2019, 11, 20, 16, 0, 0, 0] start = obspy.UTCDateTime(2019, 11, 20, 2, 0, 0, 0) end = obspy.UTCDateTime(2019, 11, 20, 16, 0, 0, 0) channel = 'IU:KIP:10:VMV' your_data = get_timeseries(client, channel=channel, start_time=start, end_time=end) title_of_plot = 'KIP Data 11_20_2019' plot = Plot(your_data, ylabel='m/s', title=title_of_plot) #yscale='log', name_of_plot = 'kip_test_11_20_2019_titles_v7' # test_11_20_2019: # https://ldas-jobs.ligo-wa.caltech.edu/~detchar/summary/day/20191120/sei/ground_blrms_overview/ plt.savefig("{}.png".format(name_of_plot))
# The :mod:`~gwpy.signal.filter_design` methods return infinite impulse # response filters by default, which, when applied, corrupt a small amount of # data at the beginning and the end of our original `TimeSeries`. # We can discard those data using the :meth:`~TimeSeries.crop` method # (for consistency we apply this to both data series): hdata = hdata.crop(*hdata.span.contract(1)) hfilt = hfilt.crop(*hfilt.span.contract(1)) # Finally, we can :meth:`~TimeSeries.plot` the original and filtered data, # adding some code to prettify the figure: from gwpy.plot import Plot plot = Plot(hdata, hfilt, figsize=[12, 6], separate=True, sharex=True, color='gwpy:ligo-hanford') ax1, ax2 = plot.axes ax1.set_title('LIGO-Hanford strain data around GW150914') ax1.text(1.0, 1.01, 'Unfiltered data', transform=ax1.transAxes, ha='right') ax1.set_ylabel('Amplitude [strain]', y=-0.2) ax2.set_ylabel('') ax2.text(1.0, 1.01, '50-250\,Hz bandpass, notches at 60, 120, 180 Hz', transform=ax2.transAxes, ha='right') plot.show() plot.close() # hide
def inject_signal_into_gwpy_timeseries(data, waveform_generator, parameters, det, power_spectral_density=None, outdir=None, label=None): """ Inject a signal into a gwpy timeseries Parameters ========== data: gwpy.timeseries.TimeSeries The time-series data into which we want to inject the signal waveform_generator: bilby.gw.waveform_generator.WaveformGenerator An initialised waveform_generator parameters: dict A dictionary of the signal-parameters to inject det: bilby.gw.detector.Interferometer The interferometer for which the data refers too power_spectral_density: bilby.gw.detector.PowerSpectralDensity Power spectral density determining the sensitivity of the detector. outdir, label: str If given, the outdir and label used to generate a plot Returns ======= data_and_signal: gwpy.timeseries.TimeSeries The data with the time-domain signal added meta_data: dict A dictionary of meta data about the injection """ from gwpy.timeseries import TimeSeries from gwpy.plot import Plot ifo = get_empty_interferometer(det) if isinstance(power_spectral_density, PowerSpectralDensity): ifo.power_spectral_density = power_spectral_density elif power_spectral_density is not None: raise TypeError( "Input power_spectral_density should be bilby.gw.detector.psd.PowerSpectralDensity " "object or None, received {}.".format( type(power_spectral_density))) ifo.strain_data.set_from_gwpy_timeseries(data) parameters_check, _ = convert_to_lal_binary_black_hole_parameters( parameters) parameters_check = { key: parameters_check[key] for key in ['mass_1', 'mass_2', 'a_1', 'a_2', 'tilt_1', 'tilt_2'] } safe_time = get_safe_signal_duration(**parameters_check) if data.duration.value < safe_time: ValueError( "Injecting a signal with safe-duration {} longer than the data {}". format(safe_time, data.duration.value)) waveform_polarizations = waveform_generator.time_domain_strain(parameters) signal = np.zeros(len(data)) for mode in waveform_polarizations.keys(): det_response = ifo.antenna_response(parameters['ra'], parameters['dec'], parameters['geocent_time'], parameters['psi'], mode) signal += waveform_polarizations[mode] * det_response time_shift = ifo.time_delay_from_geocenter(parameters['ra'], parameters['dec'], parameters['geocent_time']) dt = parameters['geocent_time'] + time_shift - data.times[0].value n_roll = dt * data.sample_rate.value n_roll = int(np.round(n_roll)) signal_shifted = TimeSeries(data=np.roll(signal, n_roll), times=data.times, unit=data.unit) signal_and_data = data.inject(signal_shifted) if outdir is not None and label is not None: fig = Plot(signal_shifted) fig.savefig('{}/{}_{}_time_domain_injected_signal'.format( outdir, ifo.name, label)) meta_data = dict() frequency_domain_signal, _ = utils.nfft( signal, waveform_generator.sampling_frequency) meta_data['optimal_SNR'] = (np.sqrt( ifo.optimal_snr_squared(signal=frequency_domain_signal)).real) meta_data['matched_filter_SNR'] = (ifo.matched_filter_snr( signal=frequency_domain_signal)) meta_data['parameters'] = parameters logger.info("Injected signal in {}:".format(ifo.name)) logger.info(" optimal SNR = {:.2f}".format(meta_data['optimal_SNR'])) logger.info(" matched filter SNR = {:.2f}".format( meta_data['matched_filter_SNR'])) for key in parameters: logger.info(' {} = {}'.format(key, parameters[key])) return signal_and_data, meta_data
# Then we can download a simulation of the GW150914 signal from GWOSC: from astropy.utils.data import get_readable_fileobj url = ("https://www.gw-openscience.org/s/events/GW150914/P150914/" "fig2-unfiltered-waveform-H.txt") with get_readable_fileobj(url) as f: signal = TimeSeries.read(f, format='txt') signal.t0 = .5 # make sure this intersects with noise time samples # Note, since this simulation cuts off before a certain time, it is # important to taper its ends to zero to avoid ringing artifacts. # We can accomplish this using the # :meth:`~gwpy.timeseries.TimeSeries.taper` method. signal = signal.taper() # Since the time samples overlap, we can inject this into our noise data # using :meth:`~gwpy.types.series.Series.inject`: data = noise.inject(signal) # Finally, we can visualize the full process in the time domain: from gwpy.plot import Plot plot = Plot(noise, signal, data, separate=True, sharex=True, sharey=True) plot.gca().set_epoch(0) plot.show() # We can clearly see that the loud GW150914-like signal has been layered # on top of Gaussian noise with the correct amplitude and phase evolution.
frequencies so that excess power at any frequency is more obvious. We demonstrate below with an auxiliary signal recording transmitted power in one of the interferometer arms, which recorded two large glitches with a frequency of around 5-50Hz. """ __author__ = "Duncan Macleod <*****@*****.**>" __currentmodule__ = 'gwpy.timeseries' # First, we import the `TimeSeries` and :meth:`~TimeSeries.get` the data: from gwpy.timeseries import TimeSeries data = TimeSeries.get('H1:ASC-Y_TR_A_NSUM_OUT_DQ', 1123084671, 1123084703) # Now, we can `~TimeSeries.whiten` the data to enhance the higher-frequency # content white = data.whiten(4, 2) # and can `~TimeSeries.plot` both the original and whitened data from gwpy.plot import Plot plot = Plot(data, white, separate=True, sharex=True) plot.axes[0].set_ylabel('Y-arm power [counts]', fontsize=16) plot.axes[1].set_ylabel('Whitened amplitude', fontsize=16) plot.show() # Here we see two large spikes that are completely undetected in the raw # `TimeSeries`, but are very obvious in the whitened data. We can also see # tapering effects at the boundaries as the whitening filter settles in, # meaning that the first and last ~second of data are corrupted and should # be discarded before further processing.
try: Max_Amp = 10**np.max(x[pks[(pks > 1200) & (pks < 4800)]]) Max_Amp_Loc = pks[np.argmax(x[pks[(pks > 1200) & (pks < 4800)]])] except: print("An exception occured, peak likely to be out of range") print("Max_Amp = {} nm/s, Max_Amp_Loc = {}".format(Max_Amp, Max_Amp_Loc)) print(' ') ########################### SAVE RESULTS ############################# if saveData: np.savetxt(fileName, dataX) print('Data saved to {}'.format(fileName)) if saveImage: plot = Plot(DATA, figsize=(12, 6), sharex=True, yscale='log') ax1 = plot.axes for ifo, ax in zip(('Livingston'), (ax1)): ax.legend([ 'ITMY-X', 'ITMY-Y', 'ITMY-Z', 'ETMY-X', 'ETMY-Y', 'ETMY-Z', 'ETMX-X', 'ETMX-Y', 'ETMX-Z' ]) #ax.text(1.01, 0.5, ifo, ha='left', va='center', transform=ax.transAxes,fontsize=18) ax.set_ylabel('Ground motion [$ nm/s $]') ax.set_title('Magnitude {} earthquake: Impact on {}'.format(MAG, IFO)) plot.savefig(figName) print('Figure saved to {}'.format(figName)) if saveResult: np.savetxt(resultName, (Max_Amp, Max_Amp_Loc)) print('Result saved to {}'.format(resultName))
from gwpy.timeseries import TimeSeries from gwpy.plot import Plot h1 = TimeSeries.fetch_open_data('H1', 1126259457, 1126259467) h1b = h1.bandpass(50, 250).notch(60).notch(120) l1 = TimeSeries.fetch_open_data('L1', 1126259457, 1126259467) l1b = l1.bandpass(50, 250).notch(60).notch(120) plot = Plot(figsize=(12, 4.8)) ax = plot.gca(xscale='auto-gps') ax.plot(h1b, color='gwpy:ligo-hanford', label='LIGO-Hanford') ax.plot(l1b, color='gwpy:ligo-livingston', label='LIGO-Livingston') ax.set_epoch(1126259462.427) ax.set_xlim(1126259462, 1126259462.6) ax.set_ylim(-1e-21, 1e-21) ax.set_ylabel('Strain noise') ax.legend() plot.show()
bm = b.mean() delta = bm - am ad = a + delta dist = np.zeros(len(a)) xf = 1000000 xfi = 1 / xf ad = a.copy() bd = b.copy() thresh = 10000000 for i in range(len(a)): dist[i] = 1 / np.linalg.norm(a[i] - b[i]) if dist[i] < -1E-6: ad[i] = am bd[i] = bm return dist, ad, bd # time=np.arange(0, 100, 0.1); # a= TimeSeries(np.sin(time)) # b= TimeSeries(np.sin(time*1.5)) # plot=Plot([a,b, dist]) # plot.show() hdata = TimeSeries.fetch_open_data('H1', 1126259446, 1126259478, cache=True) ldata = TimeSeries.fetch_open_data('L1', 1126259446, 1126259478, cache=True) d, hl, ll = distance(hdata, ldata) print(d) plot = Plot([hdata, ldata], d, [hl, ll]) plot.show()
noisefd = noise.fft() # We can now easily inject a loud sinusoid of unit amplitude at, say, # 30 Hz. To do this, we use :meth:`~gwpy.types.series.Series.inject`. import numpy from gwpy.frequencyseries import FrequencySeries signal = FrequencySeries(numpy.array([1.]), f0=30, df=noisefd.df) injfd = noisefd.inject(signal) # We can then visualize the data before and after injection in the frequency # domain: from gwpy.plot import Plot plot = Plot(numpy.abs(noisefd), numpy.abs(injfd), separate=True, sharex=True, sharey=True, xscale='log', yscale='log') plot.show() plot.close() # hide # Finally, for completeness we can visualize the effect before and after # injection back in the time domain: inj = injfd.ifft() plot = Plot(noise, inj, separate=True, sharex=True, sharey=True, figsize=(12, 6)) plot.show() plot.close() # hide # We can see why sinusoids are easier to inject in the frequency domain: # they only require adding at a single frequency.