def test_template_grid(self): templates = template_grid(stations=self.stations, nodes=self.nodes, travel_times=self.travel_times, phase='P') self.assertEqual(len(templates), 20) templates = template_grid(stations=self.stations, nodes=self.nodes, travel_times=self.travel_times, phase='S') self.assertEqual(len(templates), 20) with self.assertRaises(IOError): template_grid(stations=self.stations, nodes=self.nodes, travel_times=self.travel_times, phase='bob') templates = template_grid(stations=self.stations, nodes=self.nodes, travel_times=self.travel_times, phase='S', phaseout='S') self.assertEqual(len(templates), 20) templates = template_grid(stations=self.stations, nodes=self.nodes, travel_times=self.travel_times, phase='S', phaseout='all', flength=100) self.assertEqual(len(templates), 20) templates = template_grid(stations=self.stations, nodes=self.nodes, travel_times=self.travel_times, phase='S', phaseout='both', flength=100) self.assertEqual(len(templates), 20)
def generate_synth_data(nsta=5, ntemplates=3, nseeds=100, samp_rate=20.0, t_length=3.0, max_amp=10.0, max_lag=20, debug=0): """ Generate a synthetic dataset to be used for testing. This will generate both templates and data to scan through. Templates will be generated using the utils.synth_seis functions. The day of data will be random noise, with random signal-to-noise ratio copies of the templates randomly seeded throughout the day. It also returns the seed times and signal-to-noise ratios used. :type nsta: int :param nsta: Number of stations to generate data for < 15. :type ntemplates: int :param ntemplates: Number of templates to generate, will be generated \ with random arrival times. :type nseeds: int :param nseeds: Number of copies of the template to seed within the \ day of noisy data for each template. :type samp_rate: float :param samp_rate: Sampling rate to use in Hz :type t_length: float :param t_length: Length of templates in seconds. :type max_amp: float :param max_amp: Maximum signal-to-noise ratio of seeds. :type max_lag: Maximum lag time in seconds (randomised). :param max_lag: float :type debug: int :param debug: Debug level, bigger the number, the more plotting/output. :returns: Templates: List of obspy.Stream, Data: obspy.Stream of \ seeded noisy data, Seeds: dictionary of seed SNR and time with \ time in samples. """ from eqcorrscan.utils import synth_seis import numpy as np from obspy import UTCDateTime # Generate random arrival times t_times = np.abs(np.random.random([nsta, ntemplates])) * max_lag # Generate random node locations - these do not matter as they are only # used for naming lats = np.random.random(ntemplates) * 90.0 lons = np.random.random(ntemplates) * 90.0 depths = np.abs(np.random.random(ntemplates) * 40.0) nodes = zip(lats, lons, depths) # Generating a 5x3 array to make 3 templates stations = ['ALPH', 'BETA', 'GAMM', 'KAPP', 'ZETA', 'BOB', 'MAGG', 'ALF', 'WALR', 'ALBA', 'PENG', 'BANA', 'WIGG', 'SAUS', 'MALC'] if debug > 1: print(nodes) print(t_times) print(stations[0:nsta]) templates = synth_seis.template_grid(stations=stations[0:nsta], nodes=nodes, travel_times=t_times, phase='S', samp_rate=samp_rate, flength=int(t_length * samp_rate)) if debug > 2: for template in templates: print(template) template.plot(size=(800, 600), equal_scale=False) # Now we want to create a day of synthetic data seeds = [] data = templates[0].copy() # Copy a template to get the correct length # and stats for data, we will overwrite the data on this copy for tr in data: tr.data = np.zeros(86400 * int(samp_rate)) # Set all the traces to have a day of zeros tr.stats.starttime = UTCDateTime(0) for i, template in enumerate(templates): impulses = np.zeros(86400 * int(samp_rate)) # Generate a series of impulses for seeding # Need three seperate impulse traces for each of the three templates, # all will be convolved within the data though. impulse_times = np.random.randint(86400 * int(samp_rate), size=nseeds) impulse_amplitudes = np.random.randn(nseeds) * max_amp # Generate amplitudes up to maximum amplitude in a normal distribution seeds.append({'SNR': impulse_amplitudes, 'time': impulse_times}) for j in range(nseeds): impulses[impulse_times[j]] = impulse_amplitudes[j] # We now have one vector of impulses, we need nsta numbers of them, # shifted with the appropriate lags mintime = min([template_tr.stats.starttime for template_tr in template]) for j, template_tr in enumerate(template): offset = int((template_tr.stats.starttime - mintime) * samp_rate) pad = np.zeros(offset) tr_impulses = np.append(pad, impulses)[0:len(impulses)] # Convolve this with the template trace to give the daylong seeds data[j].data += np.convolve(tr_impulses, template_tr.data)[0:len(impulses)] if debug > 2: data.plot(starttime=UTCDateTime(0) + impulse_times[0] / samp_rate - 3, endtime=UTCDateTime(0) + impulse_times[0] / samp_rate + 15) # Add the noise for tr in data: noise = np.random.randn(86400 * int(samp_rate)) tr.data += noise / max(noise) if debug > 2: tr.plot() return templates, data, seeds
# We should trim the grid to the area we want to work in print 'Cutting the grid' stations, nodes, travel_times = bright_lights._resample_grid(stations, allnodes, alltravel_times, brightdef.mindepth, brightdef.maxdepth, brightdef.corners, brightdef.resolution) del allnodes, alltravel_times # Check that we still have a grid! if len(nodes) == 0: raise IOError("You have no nodes left") # Call the template generation function - generate at 100 Hz then downsample synth_templates=synth_seis.template_grid(stations, nodes, travel_times, 'S', \ PS_ratio=brightdef.ps_ratio, samp_rate=100,\ flength=int(100*templatedef.length), \ phaseout=template_phaseout) print 'We have '+str(len(synth_templates))+' synthetic templates' # Write out the synthetics! i=0 template_names=[] # List of the template names, which will be the node location templates=[] for synth in synth_templates: # We need the data to be in int32 stations=[tr.stats.station for tr in synth if tr.stats.station not in ['WHAT','POCR']] if len(list(set(stations))) < 5: # Only write and use templates with at least five stations print 'too few stations' print stations i+=1