def set_from_channel_name(self, channel, duration, start_time, sampling_frequency): """ Set the `frequency_domain_strain` by fetching from given channel using gwpy.TimesSeries.get(), which dynamically accesses either frames on disk, or a remote NDS2 server to find and return data. This function also verifies that the specified channel is given in the correct format. Parameters ========== channel: str Channel to look for using gwpy in the format `IFO:Channel` duration: float The data duration (in s) start_time: float The GPS start-time of the data sampling_frequency: float The sampling frequency (in Hz) """ from gwpy.timeseries import TimeSeries channel_comp = channel.split(':') if len(channel_comp) != 2: raise IndexError('Channel name must have format `IFO:Channel`') self._times_and_frequencies = CoupledTimeAndFrequencySeries( duration=duration, sampling_frequency=sampling_frequency, start_time=start_time) logger.info('Fetching data using channel {}'.format(channel)) strain = TimeSeries.get(channel, start_time, start_time + duration) strain = strain.resample(sampling_frequency) self.set_from_gwpy_timeseries(strain)
def plot_singleRTN(conf, start, end, fres, freq_tot, total): status = 0 ch = conf['chan'] try: data = TimeSeries.get(ch, start, end, host='k1nds0', port=8088) except: return 1, ch + ' cannot be loaded.' spe = data.asd(1. / fres, 1. / fres / 2.) freq = spe.frequencies.to_value() ch_spe = spe.value tf = np.zeros(len(freq)) + 1. #print('size of total: '+str(len(total))) #print('size of freq: '+str(len(freq))) if conf['tf_xml'] != 'None': ## add tf_xml status, tfxml = loadxmltf(conf, freq) if status == 1: return status, tfxml else: tf = tf * tfxml if conf['zz'] != 'None': ## add zpk status, tfzpk = loadzpktf(conf, freq) tf = tf * tfzpk if 'tf_txt' in conf: if conf['tf_txt'] == '': tf = tf elif conf['tf_txt'] == 'None': tf = tf else: status, tftxt = loadtxttf(conf, freq) if status == 1: return status, tftxt else: tf = tf * tftxt spe = ch_spe * tf # interpolate for total if max(freq) < max(freq_tot): freq = np.append(freq, max(freq_tot)) spe = np.append(spe, 0.) if min(freq) > min(freq_tot): freq = np.append(min(freq_tot), freq) spe = np.append(0., spe) spe_interp = interpolate.interp1d(freq, spe) total = np.sqrt(total * total + spe_interp(freq_tot) * spe_interp(freq_tot)) return status, total, freq, spe
def fetch_data(ifo, event_time, duration=8, sample_frequency=4096, verbose=False, **kwargs): """Fetch raw data around a glitch Parameters: ifo (str): event_time (str): duration (int, optional): sample_frequency (int, optional): verbose (bool, optional): Returns: a `gwpy.timeseries.TimeSeries` """ # find closest sample time to event time center_time = (np.floor(event_time) + np.round( (event_time - np.floor(event_time)) * sample_frequency) / sample_frequency) # determine segment start and stop times start_time = round(center_time - duration / 2) stop_time = start_time + duration frametype = kwargs.pop('frametype', None) frametype = '{0}_HOFT_{1}'.format(ifo, frametype) try: channel_name = '{0}:GDS-CALIB_STRAIN'.format(ifo) data = TimeSeries.get(channel_name, start_time, stop_time, frametype=frametype, verbose=verbose).astype('float64') except: TimeSeries.fetch_open_data(ifo, start_time, stop_time, verbose=verbose) if data.sample_rate.decompose().value != sample_frequency: data = data.resample(sample_frequency) return data
def Grab_Series(start, end, channel, frame, nproc): """Return a list of Time Series representing the known Segments from within [start ... end) Arguments: start -- GPS time. All times in all output segments are at or after this time. end -- GPS time. All times in all output segments are at or before this time. channel -- String for the channel from which all Time Series in (start, end) will be obtained. frame -- String such as 'L1_R' informed by desired observatory and type of frame. nproc -- Integer for the number of processors to use in reading each time series. Returns: The list of Time Series.""" modesl = [] for ends in Seg_Split(start, end, frame): modes = TimeSeries.get(channel, ends[0], ends[1], frametype=frame, verbose=True, nproc=nproc) modesl.append(modes) return modesl
def plot_DARM(start, end, fres, figval=1): ch = 'K1:CAL-CS_PROC_DARM_DISPLACEMENT_DQ' try: data = TimeSeries.get(ch, start, end, host='k1nds0', port=8088) except: return 1, 'DARM data cannot be obtained. Try with more recent data.' spectrum = data.asd(1. / fres, 1. / fres / 2.) tf = sig.ZerosPolesGain([10., 10., 10., 10., 10], [1., 1., 1., 1., 1.], 1.e-14) freq, mag, phase = sig.bode(tf, spectrum.frequencies.to_value()) darm = spectrum.value * (10.**(mag / 20.)) fig = plt.figure(figval) plt.loglog(freq, darm, label='DARM') #plt.loglog(spectrum.frequencies,spectrum.value,label='DARM') plt.ylabel(r'Displacement [m/$\sqrt{\rm Hz}$]') plt.xlabel('Frequency [Hz]') plt.legend() plt.grid(True) return 0, freq
def get_darm_blrms(pad, segs, chunk, target_chan, frtype): # Get DARM BLRMS srate = 16384. filt = sig.firwin(int(2 * pad * srate), [25., 59.9], nyq=srate / 2., window='hann', pass_zero=False) darm_blrms_chunks = [] for t1, t2 in chunk_segments(segs, chunk, pad): print 'Getting chunk', t1, t2 data = TimeSeries.get(target_chan, t1 - 1, t2, frtype, nproc=4, verbose=True) assert data.sample_rate.value == srate tmp_bp = 1.e21 * fir.apply_fir( data, filt, new_sample_rate=256, deriv=False) darm_blrms_chunks.append(tmp_bp[128:-128].rms(1.).value) return darm_blrms_chunks
def plot_DARM(start, end, fres, figval=1): ch = 'K1:CAL-CS_PROC_DARM_DISPLACEMENT_DQ' # gps_beg = int(to_gps( start )) # gps_end = int(to_gps( end )) # gps_beg_head = int(gps_beg/100000) # gps_end_head = int(gps_end/100000) # if gps_beg_head == gps_end_head: # cache_file="/home/devel/cache/Cache_GPS/%s.cache" % gps_beg_head # else: # # merge two cache file # cache1="/home/devel/cache/Cache_GPS/%s.cache" % gps_beg_headelse # cache2="/home/devel/cache/Cache_GPS/%s.cache" % gps_end_head # cache_file="/var/www/html/past_data_viewer/data/%s_%s.cache" % (gps_beg, gps_end) # with open(cache_file, 'w') as outfile: # for i in [cache1, cache2]: # with open(i) as infile: # outfile.write(infile.read()) try: #data = TimeSeries.read(cache_file, ch, start=gps_beg, end=gps_end, nproc=4) data = TimeSeries.get(ch, start, end, host='k1nds2', port=8088) except: return 1, 'DARM data cannot be obtained. Try with more recent data. %d %d' % ( gps_beg, gps_end) spectrum = data.asd(1. / fres, 1. / fres / 2.) tf = sig.ZerosPolesGain([10., 10., 10., 10., 10], [1., 1., 1., 1., 1.], 1.e-14) freq, mag, phase = sig.bode(tf, spectrum.frequencies.to_value()) darm = spectrum.value * (10.**(mag / 20.)) fig = plt.figure(figval) plt.loglog(freq, darm, label='DARM') #plt.loglog(spectrum.frequencies,spectrum.value,label='DARM') plt.ylabel(r'Displacement [m/$\sqrt{\rm Hz}$]') plt.xlabel('Frequency [Hz]') plt.legend() plt.grid(True) return 0, freq
to calculate discrete PSDs for each stride. This is fine for long-duration data, but give poor resolution when studying short-duration phenomena. The `~TimeSeries.spectrogram2` method allows for highly-overlapping FFT calculations to over-sample the frequency content of the input `TimeSeries` to produce a much more feature-rich output. """ __author__ = "Duncan Macleod <*****@*****.**>" __currentmodule__ = 'gwpy.timeseries' # As with the other `~gwpy.spectrogram.Spectrogram` examples, we import the # `TimeSeries` class, and :meth:`~TimeSeries.get` the data, but in this # example we only need 5 seconds of datam, from gwpy.timeseries import TimeSeries gwdata = TimeSeries.get('L1:OAF-CAL_DARM_DQ', 'Feb 28 2015 06:02:05', 'Feb 28 2015 06:02:10') # Now we can call the `~TimeSeries.spectrogram2` method of `gwdata` to # calculate our over-dense `~gwpy.spectrogram.Spectrogram` specgram = gwdata.spectrogram2(fftlength=0.15, overlap=0.14)**(1 / 2.) # To whiten the `specgram` we can use the :meth:`~Spectrogram.ratio` method # to divide by the overall median: medratio = specgram.ratio('median') # Finally, we make a plot: plot = medratio.plot(norm='log', vmin=0.5, vmax=10) plot.set_yscale('log') plot.set_ylim(40, 8192) plot.add_colorbar(label='Amplitude relative to median') plot.set_title('L1 $h(t)$ with noise interference')
from gwpy.timeseries import TimeSeries hoft = TimeSeries.get('L1:GDS-CALIB_STRAIN', 1172489751, 1172489815) aux = TimeSeries.get('L1:PSL-ISS_PDA_REL_OUT_DQ', 1172489751, 1172489815)
#!/usr/bin/python import numpy as np from gwpy.timeseries import TimeSeries O1_start = 1126569617 #O1_end = 1136649617 O1_end = O1_start + 2 for ifo in ['H1', 'L1']: channels = ['{0}:ISI-GND_STS_HAM2_Z_DQ'.format(ifo),'{0}:ISI-GND_STS_HAM2_X_DQ'.format(ifo),'{0}:ISI-GND_STS_HAM2_Y_DQ'.format(ifo),'{0}:ISI-GND_STS_HAM5_Z_BLRMS_30M_100M'.format(ifo),'{0}:ISI-GND_STS_HAM5_X_BLRMS_30M_100M'.format(ifo),'{0}:ISI-GND_STS_HAM5_Y_BLRMS_30M_100M'.format(ifo)] for channel in channels: print('Getting time series') velocities = TimeSeries.get(channel,O1_start,O1_end) print('Time series done') acceleration = np.diff(velocities) print(acceleration.value)
def make_q_scans(event_time, **kwargs): """Classify triggers in this table Parameters: ---------- Returns ------- """ # Parse Keyword Arguments config = kwargs.pop('config', GravitySpyConfigFile()) timeseries = kwargs.pop('timeseries', None) source = kwargs.pop('source', None) channel_name = kwargs.pop('channel_name', None) frametype = kwargs.pop('frametype', None) verbose = kwargs.pop('verbose', False) if verbose: logger = log.Logger('Gravity Spy: Making Q Scans') if (timeseries is None) and (channel_name is None): raise ValueError("If not directly passing a timeseries, then " "the user must pass channel_name") ########################################################################### # Parse Ini File # ########################################################################### sample_frequency = config.sample_frequency block_time = config.block_time search_frequency_range = config.search_frequency_range search_q_range = config.search_q_range plot_time_ranges = config.plot_time_ranges plot_normalized_energy_range = config.plot_normalized_energy_range if verbose: logger.info(""" You have chosen the following parameters Sample Frequency : {0} Block Time : {1} Frequency Range : {2} Q Range : {3} Spectrogram Colorbar Range: {4} """.format(sample_frequency, block_time, search_frequency_range, search_q_range, plot_time_ranges, plot_normalized_energy_range)) # find closest sample time to event time center_time = ( numpy.floor(event_time) + numpy.round((event_time - numpy.floor(event_time)) * sample_frequency) / sample_frequency ) # determine segment start and stop times start_time = round(center_time - block_time / 2) stop_time = start_time + block_time # Read in the data if timeseries: data = timeseries.crop(start_time, stop_time, verbose=verbose) elif source: if verbose: logger.info('Reading Data From Source ...') data = TimeSeries.read(source=source, channel=channel_name, start=start_time, end=stop_time, verbose=verbose) else: if verbose: logger.info('Fetching Data...') data = TimeSeries.get(channel_name, start_time, stop_time, frametype=frametype, verbose=verbose).astype('float64') # resample data if verbose: logger.info('Resampling Data...') if data.sample_rate.decompose().value != sample_frequency: data = data.resample(sample_frequency) # Cropping the results before interpolation to save on time and memory # perform the q-transform if verbose: logger.info('Processing Q Scans...') specsgrams = [] for time_window in plot_time_ranges: duration_for_plot = time_window/2 try: outseg = Segment(center_time - duration_for_plot, center_time + duration_for_plot) q_scan = data.q_transform(qrange=tuple(search_q_range), frange=tuple(search_frequency_range), gps=center_time, search=0.5, tres=0.002, fres=0.5, outseg=outseg, whiten=True) q_value = q_scan.q q_scan = q_scan.crop(center_time-time_window/2, center_time+time_window/2) except: outseg = Segment(center_time - 2*duration_for_plot, center_time + 2*duration_for_plot) q_scan = data.q_transform(qrange=tuple(search_q_range), frange=tuple(search_frequency_range), gps=center_time, search=0.5, tres=0.002, fres=0.5, outseg=outseg, whiten=True) q_value = q_scan.q q_scan = q_scan.crop(center_time-time_window/2, center_time+time_window/2) specsgrams.append(q_scan) if verbose: logger.info('The most significant q value is {0}'.format(q_value)) return specsgrams, q_value
parts of the detector, closely monitoring mechanical subsystems and environmental conditions. We can cross-correlate data from these sensors with the primary gravitational wave data to look for evidence of terrestrial noise. We demonstrate below a prominent 'whistle glitch' in the gravitational wave channel, which is also witnessed by a photodiode in the Pre-Stabilized Laser (PSL) chamber. This example uses data from the LIGO Livingston detector during Advanced LIGO's second observing run. """ __author__ = "Alex Urban <*****@*****.**>" __currentmodule__ = 'gwpy.timeseries' # First, we import the `TimeSeries` and :meth:`~TimeSeries.get` the data: from gwpy.timeseries import TimeSeries hoft = TimeSeries.get('L1:GDS-CALIB_STRAIN', 1172489751, 1172489815) aux = TimeSeries.get('L1:PSL-ISS_PDA_REL_OUT_DQ', 1172489751, 1172489815) # Next, we should `~TimeSeries.whiten` the data to enhance the higher-frequency # content and make a more faithful comparison between data streams. whoft = hoft.whiten(8, 4) waux = aux.whiten(8, 4) # We can now cross-correlate these channels: mfilter = waux.crop(1172489782.57, 1172489783.57) snr = whoft.correlate(mfilter).abs() # and plot the resulting normalised signal-to-noise ratio: plot = snr.crop(1172489782.07, 1172489784.07).plot() plot.axes[0].set_epoch(1172489783.07) plot.axes[0].set_ylabel('Signal-to-noise ratio', fontsize=16)
#!/usr/bin/python import sys from gwpy.timeseries import TimeSeries sys.stdout.write("starting first time series \n") #H1_channel_lockstatus_data_1 = TimeSeries.get('H1:DMT-DC_READOUT_LOCKED',float(pw_arrival_time),float(float(pw_arrival_time) + float(options.time_after_p_wave))) H1_channel_lockstatus_data_1 = TimeSeries.get('H1:DMT-DC_READOUT_LOCKED',float(pw_arrival_time)-10,float(rw_arrival_time)) print >> sys.stdout.write("data gathered") firstcheck = H1_channel_lockstatus_data_1[0] if firstcheck == 1: for dataoutput in H1_channel_lockstatus_data_1[1:]: if dataoutput == 0: locklosscheck1 = "Y" break else: locklosscheck1 = "N" break else: locklosscheck1 = "Z" print >> sys.stdout.write("first timeseries complete \n") #H1_channel_lockstatus_data_2 = TimeSeries.get('H1:LSC-POP_A_LF_OUT_DQ',float(pw_arrival_time),float(float(pw_arrival_time) + float(options.time_after_p_wave))) H1_channel_lockstatus_data_2 = TimeSeries.get('H1:LSC-POP_A_LF_OUT_DQ',float(pw_arrival_time)-10,float(rw_arrival_time)) secondcheck = H1_channel_lockstatus_data_2[0] if secondcheck > 10000: for dataoutput in H1_channel_lockstatus_data_2: if dataoutput < 10: locklosscheck2 = "Y" break
from gwpy.timeseries import TimeSeries data = TimeSeries.get('H1:ASC-Y_TR_A_NSUM_OUT_DQ', 1123084671, 1123084703)
from gwpy.timeseries import TimeSeries gwdata = TimeSeries.get('H1:LDAS-STRAIN', 'September 16 2010 06:40', 'September 16 2010 06:50') spectrum = gwdata.asd(8, 4)
#------------------------------------------------------------------------------- # Collect Data and Run Filter #------------------------------------------------------------------------------- chan1 = 'H1:SQZ-OMC_TRANS_RF3_Q_NORM_DQ' darm = 'H1:GDS-CALIB_STRAIN' st = 1241098218 ifo = 'H1' fs = 256 dur = 720 M = 32 low = 75 high = 105 # collect the data darm = TimeSeries.get(darm, st, st+dur, nproc=4, verbose=False) darm = darm.resample(fs) darm = darm.value darm_copy = np.copy(darm) darm = butter_filter(darm, low=low, high=high, fs=fs) data = TimeSeries.get(chan1, st, st+dur, nproc=4) if data.sample_rate.value != fs: data = data.resample(fs) wit = data.value wit = butter_filter(wit, low=low, high=high, fs=fs) wit = wit.reshape(dur*fs) clean = darm_copy - nlms(darm, wit, M=1, leak=0.0, psi=1e-6, mu=0.5) #-------------------------------------------------------------------------------
from gwosc.datasets import event_gps from gwpy.timeseries import TimeSeries gps = event_gps("GW170814") start = int(gps) - 100 end = int(gps) + 100 data = TimeSeries.get("H1:IMC-PWR_IN_OUT_DQ", start, end, host="losc-nds.ligo.org") plot = data.plot(ylabel="Power [W]") plot.show()
changed appreciably. """ __author__ = "Duncan Macleod <*****@*****.**>" __currentmodule__ = "gwpy.timeseries" # First, we import the `TimeSeries` from gwpy.timeseries import TimeSeries # And we set the times of our investigation: goodtime = 1061800700 badtime = 1061524816 duration = 120 # Next we :meth:`~TimeSeries.get` the data: gooddata = TimeSeries.get("L1:PSL-ISS_PDB_OUT_DQ", goodtime, goodtime + duration) baddata = TimeSeries.get("L1:PSL-ISS_PDB_OUT_DQ", badtime, badtime + duration) # and calculate an `amplitude spectral density (ASD) <TimeSeries.asd>` using a 4-second Fourier transform with a 2-second overlap: goodasd = gooddata.asd(4, 2) badasd = baddata.asd(4, 2) # Lastly, we make a plot of the data by `plotting <FrequencySeries.plot>` one `~gwpy.frequencyseries.FrequencySeries`, and then adding the second: plot = badasd.plot(label="Noisy data") ax = plot.gca() ax.plot(goodasd, label="Clean data") ax.set_xlabel("Frequency [Hz]") ax.set_xlim(10, 8000) ax.set_ylabel(r"Noise ASD [1/$\sqrt{\mathrm{Hz}}$]") ax.set_ylim(1e-6, 5e-4) ax.grid(True, "both", "both")
print "Either --segment-file, or both start and end time must be provided." exit(2) st=segs[0].start et=segs[-1].end chunk=4096 pad=256 target_chan=ifo+':GDS-CALIB_STRAIN' frtype=ifo+"_HOFT_C00" # Get DARM BLRMS srate=16384. filt=sig.firwin(int(2*pad*srate),[65.,115],nyq=srate/2.,window='hann',pass_zero=False) darm_blrms_chunks=[] for t1,t2 in chunk_segments(segs,chunk,pad): print 'Getting chunk', t1, t2 data=TimeSeries.get(target_chan,t1,t2,frtype,nproc=4,verbose=True) assert data.sample_rate.value==srate tmp_bp=1.e21*fir.apply_fir(data, filt, new_sample_rate=256, deriv=False) darm_blrms_chunks.append(tmp_bp[128:-128].rms(1./16.).value) # Turn into a big array and dump to a file full_data=array(concatenate(darm_blrms_chunks)) if args.path: save("%s/%s-DARMBLRMS-%u-%u.npy"%(args.path,ifo,st,et-st),full_data) else: save("%s-DARMBLRMS-%u-%u.npy"%(ifo,st,et-st),full_data) print 'You are done!'
high-frequency content, making discerning high-frequency features difficult. We employ a technique called 'whitening' to normalize the power at all 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 plot = data.plot() plot.add_timeseries(white, newax=True, sharex=plot.axes[0]) plot.axes[0].set_xlabel('') 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.
"""Calculating and plotting a `Spectrum` I'm interested in the level of ground motion surrounding a particular time during commissioning of the Advanced LIGO Livingston Observatory. I don't have access to the frame files on disk, so I'll need to use NDS. """ __author__ = "Duncan Macleod <*****@*****.**>" __currentmodule__ = 'gwpy.spectrum' # In order to generate a `Spectrum` we need to import the # `~gwpy.timeseries.TimeSeries` and :meth:`~gwpy.timeseries.TimeSeries.get` # the data: from gwpy.timeseries import TimeSeries lho = TimeSeries.get( 'H1:LDAS-STRAIN,rds', 'August 1 2010', 'August 1 2010 00:02') llo = TimeSeries.get( 'L1:LDAS-STRAIN,rds', 'August 1 2010', 'August 1 2010 00:02') # We can then call the :meth:`~gwpy.timeseries.TimeSeries.asd` method to # calculated the amplitude spectral density for each # `~gwpy.timeseries.TimeSeries`: lhoasd = lho.asd(2, 1) lloasd = llo.asd(2, 1) # We can then :meth:`~Spectrum.plot` the spectra plot = lhoasd.plot(color='b', label='LHO') ax = plot.gca() ax.plot(lloasd, color='g', label='LLO') ax.set_xlim(40, 4096) ax.set_ylim(1e-23, 7.5e-21)
to calculate discrete PSDs for each stride. This is fine for long-duration data, but give poor resolution when studying short-duration phenomena. The `~TimeSeries.spectrogram2` method allows for highly-overlapping FFT calculations to over-sample the frequency content of the input `TimeSeries` to produce a much more feature-rich output. """ __author__ = "Duncan Macleod <*****@*****.**>" __currentmodule__ = 'gwpy.timeseries' # As with the other `~gwpy.spectrogram.Spectrogram` examples, we import the # `TimeSeries` class, and :meth:`~TimeSeries.get` the data, but in this # example we only need 5 seconds of datam, from gwpy.timeseries import TimeSeries gwdata = TimeSeries.get( 'L1:OAF-CAL_DARM_DQ', 'Feb 28 2015 06:02:05', 'Feb 28 2015 06:02:10') # Now we can call the `~TimeSeries.spectrogram2` method of `gwdata` to # calculate our over-dense `~gwpy.spectrogram.Spectrogram` specgram = gwdata.spectrogram2(fftlength=0.15, overlap=0.14) ** (1/2.) # To whiten the `specgram` we can use the :meth:`~Spectrogram.ratio` method # to divide by the overall median: medratio = specgram.ratio('median') # Finally, we make a plot: plot = medratio.plot(norm='log', vmin=0.5, vmax=10) plot.set_yscale('log') plot.set_ylim(40, 8192) plot.add_colorbar(label='Amplitude relative to median') plot.set_title('L1 $h(t)$ with noise interference')
from gwpy.timeseries import TimeSeries gwdata = TimeSeries.get('H1:LDAS-STRAIN', 'September 16 2010 06:40', 'September 16 2010 06:50', verbose=True)
# GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GWpy. If not, see <http://www.gnu.org/licenses/> """Calculating and plotting a `SpectralVariance` histogram """ __author__ = "Duncan Macleod <*****@*****.**>" __currentmodule__ = 'gwpy.spectrum' # In order to generate a `SpectralVariance` histogram we need to import the # `~gwpy.timeseries.TimeSeries` and :meth:`~gwpy.timeseries.TimeSeries.get` # the data: from gwpy.timeseries import TimeSeries llo = TimeSeries.get( 'L1:LDAS-STRAIN,rds', 'August 1 2010', 'August 1 2010 00:10') # We can then call the :meth:`~gwpy.timeseries.TimeSeries.spectral_variance` # method of the ``llo`` `~gwpy.timeseries.TimeSeries`: variance = llo.spectral_variance(1, log=True, low=1e-24, high=1e-19, nbins=100) # We can then :meth:`~SpectralVariance.plot` the `SpectralVariance` plot = variance.plot(norm='log', vmin=0.5, vmax=100) ax = plot.gca() ax.grid() ax.set_xlim(40, 4096) ax.set_ylim(1e-24, 1e-19) ax.set_xlabel('Frequency [Hz]') ax.set_ylabel(r'GW ASD [strain/\rtHz]') ax.set_title('LIGO Livingston Observatory sensitivity variance') plot.show()
changed appreciably. """ __author__ = "Duncan Macleod <*****@*****.**>" __currentmodule__ = 'gwpy.timeseries' # First, we import the `TimeSeries` from gwpy.timeseries import TimeSeries # And we set the times of our investigation: goodtime = 1061800700 badtime = 1061524816 duration = 120 # Next we :meth:`~TimeSeries.get` the data: gooddata = TimeSeries.get('L1:PSL-ISS_PDB_OUT_DQ', goodtime, goodtime + duration) baddata = TimeSeries.get('L1:PSL-ISS_PDB_OUT_DQ', badtime, badtime + duration) # and calculate an `amplitude spectral density (ASD) <TimeSeries.asd>` using a 4-second Fourier transform with a 2-second overlap: goodasd = gooddata.asd(4, 2) badasd = baddata.asd(4, 2) # Lastly, we make a plot of the data by `plotting <FrequencySeries.plot>` one `~gwpy.frequencyseries.FrequencySeries`, and then adding the second: plot = badasd.plot(label='Noisy data') ax = plot.gca() ax.plot(goodasd, label='Clean data') ax.set_xlabel('Frequency [Hz]') ax.set_xlim(10, 8000) ax.set_ylabel(r'Noise ASD [1/$\sqrt{\mathrm{Hz}}$]') ax.set_ylim(1e-6, 5e-4) ax.grid(True, 'both', 'both')
def plot_singleRTN(conf, start, end, fres, freq_tot, total): status = 0 #print(start, end) ch = conf['chan'] # gps_beg = int(to_gps( start )) # gps_end = int(to_gps( end )) # gps_beg_head = int(gps_beg/100000) # gps_end_head = int(gps_end/100000) # if gps_beg_head == gps_end_head: # cache_file="/home/devel/cache/Cache_GPS/%s.cache" % gps_beg_head # else: # # merge two cache file # cache1="/home/devel/cache/Cache_GPS/%s.cache" % gps_beg_headelse # cache2="/home/devel/cache/Cache_GPS/%s.cache" % gps_end_head # cache_file="/var/www/html/past_data_viewer/data/%s_%s.cache" % (gps_beg, gps_end) # with open(cache_file, 'w') as outfile: # for i in [cache1, cache2]: # with open(i) as infile: # outfile.write(infile.read()) try: #data = TimeSeries.read(cache_file, ch, start=gps_beg, end=gps_end, nproc=4) data = TimeSeries.get(ch, start, end, host='k1nds2', port=8088) except: return 1, ch + ' cannot be loaded.' spe = data.asd(1. / fres, 1. / fres / 2.) freq = spe.frequencies.to_value() ch_spe = spe.value tf = np.zeros(len(freq)) + 1. #print('size of total: '+str(len(total))) #print('size of freq: '+str(len(freq))) if conf['tf_xml'] != 'None': ## add tf_xml status, tfxml = loadxmltf(conf, freq) if status == 1: return status, tfxml else: tf = tf * tfxml if conf['zz'] != 'None': ## add zpk status, tfzpk = loadzpktf(conf, freq) tf = tf * tfzpk if 'tf_txt' in conf: if conf['tf_txt'] == '': tf = tf elif conf['tf_txt'] == 'None': tf = tf else: status, tftxt = loadtxttf(conf, freq) if status == 1: return status, tftxt else: tf = tf * tftxt spe = ch_spe * tf # interpolate for total if max(freq) < max(freq_tot): freq = np.append(freq, max(freq_tot)) spe = np.append(spe, 0.) if min(freq) > min(freq_tot): freq = np.append(min(freq_tot), freq) spe = np.append(0., spe) spe_interp = interpolate.interp1d(freq, spe) total = np.sqrt(total * total + spe_interp(freq_tot) * spe_interp(freq_tot)) return status, total, freq, spe
# along with GWpy. If not, see <http://www.gnu.org/licenses/> """Calculating and plotting a `FrequencySeries` I'm interested in the level of ground motion surrounding a particular time during commissioning of the Advanced LIGO Livingston Observatory. I don't have access to the frame files on disk, so I'll need to use NDS. """ __author__ = "Duncan Macleod <*****@*****.**>" __currentmodule__ = 'gwpy.frequencyseries' # In order to generate a `FrequencySeries` we need to import the # `~gwpy.timeseries.TimeSeries` and :meth:`~gwpy.timeseries.TimeSeries.get` # the data: from gwpy.timeseries import TimeSeries lho = TimeSeries.get('H1:LDAS-STRAIN,rds', 'August 1 2010', 'August 1 2010 00:02') llo = TimeSeries.get('L1:LDAS-STRAIN,rds', 'August 1 2010', 'August 1 2010 00:02') # We can then call the :meth:`~gwpy.timeseries.TimeSeries.asd` method to # calculated the amplitude spectral density for each # `~gwpy.timeseries.TimeSeries`: lhoasd = lho.asd(2, 1) lloasd = llo.asd(2, 1) # We can then :meth:`~FrequencySeries.plot` the spectra plot = lhoasd.plot(color='b', label='LHO') ax = plot.gca() ax.plot(lloasd, color='g', label='LLO') ax.set_xlim(40, 4096) ax.set_ylim(1e-23, 7.5e-21)
# # You should have received a copy of the GNU General Public License # along with GWpy. If not, see <http://www.gnu.org/licenses/>. """Plotting a whitened `Spectrogram` I would like to study the gravitational wave strain spectrogram around the time of an interesting simulated signal during the last science run (S6). """ __author__ = "Duncan Macleod <*****@*****.**>" __currentmodule__ = 'gwpy.spectrogram' # As with :doc:`previous example <plot>`, we import the # `~gwpy.timeseries.TimeSeries` class, # :meth:`~gwpy.timeseries.TimeSeries.get` the data, and calculate a # `Spectrogram` from gwpy.timeseries import TimeSeries gwdata = TimeSeries.get('H1:LDAS-STRAIN,rds', 'September 16 2010 06:40', 'September 16 2010 06:50') specgram = gwdata.spectrogram(5, fftlength=2, overlap=1)**(1 / 2.) # To whiten the `specgram` we can use the :meth:`~Spectrogram.ratio` method # to divide by the overall median: medratio = specgram.ratio('median') # Finally, we make a plot: plot = medratio.plot(norm='log', vmin=0.1, vmax=10) plot.set_yscale('log') plot.set_ylim(40, 4096) plot.add_colorbar(label='Amplitude relative to median') plot.show()
for q_v in range(0+(pad*1000),len(tmp_q)-(pad*1000),1000): if q_v == 0+(pad*1000): small_chunksq = tmp_q[q_v,:] small_chunksq = np.asarray(small_chunksq) else: small_chunksq = np.vstack((small_chunksq,tmp_q[q_v,:])) q_chunks.append(small_chunksq) full_data.append(concatenate(position_chunks)) full_data.append(concatenate(velocity_chunks)) full_data.append(concatenate(q_chunks)) sys.exit() # Get DARM BLRMS chunk=4096 srate=16384. filt=sig.firwin(int(2*pad*srate),[50.,59.9,60.1,100.],nyq=srate/2.,window='hann',pass_zero=False) darm_blrms_chunks=[] for t1,t2 in chunk_segments(segs,chunk,pad): data=TimeSeries.get(target_chan,t1-1,t2,nproc=6,verbose=True) assert data.sample_rate.value==srate tmp_bp=1.e21*fir.apply_fir(data, filt, new_sample_rate=256, deriv=False) darm_blrms_chunks.append(tmp_bp[128:-128].rms(1.).value) darm_data.append(concatenate(darm_blrms_chunks)) # Turn into a big array and dump to a file full_data=array(full_data) darm_data=array(darm_data) save('%s-ML-%s-%s.npy' % (ifo,st,et-st),full_data) save('%s-DARMBLRMS-%s-%s.npy' % (ifo,st,et-st),darm_data)
from gwpy.timeseries import TimeSeries white = TimeSeries.get('L1:OAF-CAL_DARM_DQ', 'March 2 2015 12:00', 'March 2 2015 12:30')
def read_virgo_timeseries(source, channel, t0, gstop_or_dur, mask=False, fill_value=np.nan, remote=False): """Function to read virgo data as timeseries. This should one day be included in gwpy. Parameters ---------- source : `str` Frame file, either a full path to a ffl or gwf file, or an abbreviation like 'raw', 'trend', which are looked up in the stancard location. If omitted, defaults to 'raw', but this default value is deprecated. channel : `str` Source datastream for these data. If missing, a prefix 'V1:' is added. t0 : `~gwpy.time.LIGOTimeGPS`, `float`, `str` GPS epoch corresponding to starting time, any input parsable by `~gwpy.time.to_gps` is fine gstop_or_dur: `~gwpy.time.LIGOTimeGPS`, `float`, `str` GPS epoch corresponding to end time, any input parsable by `~gwpy.time.to_gps` is fine If a `float` < 1e6 is provided, it corresponds to a duration in seconds from `t0`. mask : `bool`, optional If mask is False, missing samples will be replaced by fill_value. If it is True, the returned FrVect will have an attribute missing, which is a mask vector that is zero for missing samples. Default : False fill_value : `float`, optional Value that is used for missing samples if mask is False. Default: np.nan remote: `bool` optional If False, use PythonVirgoTools to parse raw data files. If True, use gwpy.TimeSeries.get(), but takes longer. Default : False, assuming the script is ran on Virgo server. Examples -------- >>> from virgotools import getChannel Load the data from channel 'INJ_IMC_TRA_DC', from Sep 14 2015 09:50:45.391, and a duration of 10s >>> x = getChannel('raw', 'INJ_IMC_TRA_DC', 'Sep 14 2015 09:50:45.391', 10) That can be simply visualise: >>> import matplotlib.pyplot as plt >>> plt.plot(x.time, x.data) >>> plt.show() Same, using 2 GPS times: >>> x = getChannel('raw', 'INJ_IMC_TRA_DC', 1126259462.3910, 1126259472.3910) """ # Convert to gps times in seconds # Use the Seconds and NanoSeconds instead of ns() # Because otherwise one needs to multiply by 1e-9 # And this can cause rounding approximation sec = to_gps(t0).gpsSeconds nsec = to_gps(t0).gpsNanoSeconds tstart = str(sec) + '.' + str(nsec) gstart = float(tstart) sec = to_gps(gstop_or_dur).gpsSeconds nsec = to_gps(gstop_or_dur).gpsNanoSeconds tend = str(sec) + '.' + str(nsec) if float(tend) < 1e6: gstop = gstart + float(tend) else: gstop = float(tend) # If the script is running on Virgo's server. if not remote: from virgotools import getChannel # Parse Virgo files with getChannel(source, channel, gstart, gstop, mask=mask, fill_value=fill_value) as data: data = TimeSeries(data.data, unit=data.unit, t0=gstart, dt=data.dt, channel=channel) else: # If not running the script on Virgo's server. Takes longer # Query is working, but crashes when computing q_transform. # Data might not be the same format as with PythonVirgoTools. # Further checks required. if channel[:3] not in ['V1:', 'H1:', 'L1:']: print( 'When accessing the data outside the virgo server, the channel must start with `V1:`, `H1:` or `L1:` ' ) data = TimeSeries.get(channel, gstart, gstop) return data
def coherence(cls, channel1, channel2, st, et, overlap=None, pad=False, stride=1, resamplerate1=None, resamplerate2=None): """ Class methond that calculates coherence between two channels and return a coherence segment. Parameters ---------- channel1 : `str` Name of first channel channel2 : `str` Name of second channel st : `int` Start time et : `int` End time stride : `int`, optional, default=1 second Length of ffts overlap : `int`, optional, default=0.5 seconds Amount of overlap between ffts pad : `bool` Determines whether or not to zeropad the data when taking ffts Returns ------- segment : :class:`PEMCoherenceSegment` Coherence segment for these two channels """ # read in data if isinstance(channel1, Channel): data1 = TimeSeries.find(channel1.name, st, et, frametype=channel1.frametype) else: data1 = TimeSeries.get(channel1, st, et) if resamplerate1 is not None and resamplerate1 < data1.sample_rate.value: data1 = data1.resample(resamplerate1) if isinstance(channel2, Channel): data2 = TimeSeries.find(channel2.name, st, et, frametype=channel2.frametype) else: data2 = TimeSeries.get(channel2, st, et) if resamplerate2 is not None and resamplerate2 < data2.sample_rate.value: data2 = data2.resample(resamplerate2) # get fft spectrograms fftgram1 = cf.fftgram(data1, stride, overlap=overlap, pad=pad) fftgram2 = cf.fftgram(data2, stride, overlap=overlap, pad=pad) # cut things down if frequency arrays are too long # TODO: eventually port this over to `gwpy.spectrogram.Spectrogram.crop()` # in some way using the `gwpy.detector.Channel.frequency_range()` specified # but want to keep backwards compatability in case strings are supplied maxlen = min(fftgram1.shape[1], fftgram2.shape[1]) # take csd csd12 = cf.csdgram(fftgram1[:, :maxlen], fftgram2[:, :maxlen], stride, overlap=overlap, pad=pad) # get number of segments analyzed N = fftgram1.shape[0] # take mean of csd csd12 = np.mean(csd12, 0) # take mean of fftgrams, take abs to get psds psd1 = np.mean(np.abs(fftgram1)**2, 0) psd2 = np.mean(np.abs(fftgram2)**2, 0) # return the segment return PEMCoherenceSegment(channel1, channel2, csd12, psd1, psd2, N, st, et)
high-frequency content, making discerning high-frequency features difficult. We employ a technique called 'whitening' to normalize the power at all 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', 1123084670, 1123084800) # 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 epoch = 1123084687.570 plot = data.plot() plot.axes[0].set_ylabel('Y-arm power [counts]', fontsize=16) plot.add_timeseries(white, newax=True, sharex=plot.axes[0]) plot.axes[1].set_ylabel('Whitened amplitude', fontsize=16) plot.axes[0].set_epoch(epoch) plot.axes[1].set_epoch(epoch) plot.axes[0].set_xlim(epoch-8, epoch+8) plot.axes[1].set_xlim(epoch-8, epoch+8)
from gwpy.timeseries import TimeSeries white = TimeSeries.get( 'L1:OAF-CAL_DARM_DQ', 'March 2 2015 12:00', 'March 2 2015 12:30')
#!/usr/bin/python import numpy as np from gwpy.timeseries import TimeSeries O1_start = 1126569617 #O1_end = 1136649617 O1_end = O1_start + 2 for ifo in ['H1', 'L1']: channels = [ '{0}:ISI-GND_STS_HAM2_Z_DQ'.format(ifo), '{0}:ISI-GND_STS_HAM2_X_DQ'.format(ifo), '{0}:ISI-GND_STS_HAM2_Y_DQ'.format(ifo), '{0}:ISI-GND_STS_HAM5_Z_BLRMS_30M_100M'.format(ifo), '{0}:ISI-GND_STS_HAM5_X_BLRMS_30M_100M'.format(ifo), '{0}:ISI-GND_STS_HAM5_Y_BLRMS_30M_100M'.format(ifo) ] for channel in channels: print('Getting time series') velocities = TimeSeries.get(channel, O1_start, O1_end) print('Time series done') acceleration = np.diff(velocities) print(acceleration.value)