def test_adjoint_functions(): observed = Trace(data=np.ones(25)) synthetic = Trace(data=np.ones(25)) synthetic.data[0:13] *= 2.0 synthetic.stats.sac = {} synthetic.stats.sac['dist'] = 6000. observed.stats = synthetic.stats.copy() window_params = {} window_params['hw'] = 2.0 window_params['sep_noise'] = 1.0 window_params['win_overlap'] = False window_params['wtype'] = "hann" window_params['plot'] = False g_speed = 2000. adj, success = am.log_en_ratio_adj(observed, synthetic, g_speed, window_params) assert (success) assert (len(adj) == 25) assert (pytest.approx(adj[10]) == -0.16666666666666663) adj, success = am.windowed_waveform(observed, synthetic, g_speed, window_params) assert (success) assert (len(adj) == 25) assert (pytest.approx(adj[9]) == 1.) func = am.get_adj_func('energy_diff') adj, success = func(observed, synthetic, g_speed, window_params) assert (success) assert (len(adj) == 2) assert (type(adj) == list) assert (pytest.approx(adj[1].sum()) == 6.)
def measurement(source_config, mtype, step, ignore_net, ix_bandpass, bandpass, step_test, taper_perc, **options): """ Get measurements on noise correlation data and synthetics. options: g_speed,window_params (only needed if mtype is ln_energy_ratio or enery_diff) """ verbose = yaml.safe_load( open(os.path.join(source_config['project_path'], 'config.yml')))['verbose'] step_n = 'iteration_{}'.format(int(step)) step_dir = os.path.join(source_config['source_path'], step_n) if step_test: corr_dir = os.path.join(step_dir, 'obs_slt') else: corr_dir = os.path.join(source_config['source_path'], 'observed_correlations') files = [f for f in os.listdir(corr_dir)] files = [os.path.join(corr_dir, f) for f in files] synth_dir = os.path.join(step_dir, 'corr') columns = [ 'sta1', 'sta2', 'lat1', 'lon1', 'lat2', 'lon2', 'dist', 'az', 'baz', 'syn', 'syn_a', 'obs', 'obs_a', 'l2_norm', 'snr', 'snr_a', 'nstack' ] measurements = pd.DataFrame(columns=columns) options['window_params']['causal_side'] = True # relic for signal to noise _options_ac = copy.deepcopy(options) _options_ac['window_params']['causal_side'] = ( not (options['window_params']['causal_side'])) if files == []: msg = 'No input found!' raise ValueError(msg) for i, f in enumerate(files): # Read data try: tr_o = read(f)[0] except IOError: if verbose: print('\nCould not read data: ' + os.path.basename(f)) continue # Read synthetics synth_filename = get_synthetics_filename(os.path.basename(f), synth_dir, ignore_network=ignore_net) if synth_filename is None: continue try: tr_s = read(synth_filename)[0] except IOError: if verbose: print('\nCould not read synthetics: ' + synth_filename) continue # Assigning stats to synthetics, cutting them to right length tr_s.stats.sac = tr_o.stats.sac.copy() tr_s.data = my_centered(tr_s.data, tr_o.stats.npts) # Get all the necessary information info = get_station_info(tr_o.stats) # Collect the adjoint source adjoint_source = Stream() adjoint_source += Trace() adjoint_source[0].stats.sampling_rate = tr_s.stats.sampling_rate adjoint_source[0].stats.sac = tr_s.stats.sac.copy() # Filter if bandpass is not None: tr_o.taper(taper_perc / 100.) tr_o.filter('bandpass', freqmin=bandpass[0], freqmax=bandpass[1], corners=bandpass[2], zerophase=True) tr_s.taper(taper_perc / 100.) tr_s.filter('bandpass', freqmin=bandpass[0], freqmax=bandpass[1], corners=bandpass[2], zerophase=True) # Weight observed stack by nstack tr_o.data /= tr_o.stats.sac.user0 # Take the measurement func = rm.get_measure_func(mtype) msr_o = func(tr_o, **options) msr_s = func(tr_s, **options) # Get the adjoint source adjt_func = am.get_adj_func(mtype) adjt, success = adjt_func(tr_o, tr_s, **options) if not success: continue # timeseries-like measurements: if mtype in ['square_envelope', 'full_waveform', 'windowed_waveform']: l2_so = 0.5 * np.sum(np.power((msr_s - msr_o), 2)) snr = snratio(tr_o, **options) snr_a = snratio(tr_o, **_options_ac) info.extend([ np.nan, np.nan, np.nan, np.nan, l2_so, snr, snr_a, tr_o.stats.sac.user0 ]) adjoint_source[0].data = adjt # single value measurements: else: if mtype == 'energy_diff': l2_so = 0.5 * (msr_s - msr_o)**2 / (msr_o)**2 msr = msr_o[0] msr_a = msr_o[1] snr = snratio(tr_o, **options) snr_a = snratio(tr_o, **_options_ac) l2 = l2_so.sum() info.extend([ msr_s[0], msr_s[1], msr, msr_a, l2, snr, snr_a, tr_o.stats.sac.user0 ]) adjoint_source += adjoint_source[0].copy() for ix_branch in range(2): adjoint_source[ix_branch].data = adjt[ix_branch] adjoint_source[ix_branch].data *= ( msr_s[ix_branch] - msr_o[ix_branch]) / msr_o[ix_branch]**2 elif mtype == 'ln_energy_ratio': l2_so = 0.5 * (msr_s - msr_o)**2 msr = msr_o snr = snratio(tr_o, **options) snr_a = snratio(tr_o, **_options_ac) info.extend([ msr_s, np.nan, msr, np.nan, l2_so, snr, snr_a, tr_o.stats.sac.user0 ]) adjt *= (msr_s - msr_o) adjoint_source[0].data = adjt measurements.loc[i] = info # save the adjoint source if len(adjoint_source) == 1: adjt_filename = os.path.basename(synth_filename).rstrip('sac') +\ '{}.sac'.format(ix_bandpass) adjoint_source[0].write(os.path.join(step_dir, 'adjt', adjt_filename), format='SAC') elif len(adjoint_source) == 2: for ix_branch, branch in enumerate(['c', 'a']): adjt_filename = os.path.basename(synth_filename).\ rstrip('sac') + '{}.{}.sac'.format(branch, ix_bandpass) adjoint_source[ix_branch].write(os.path.join( step_dir, 'adjt', adjt_filename), format='SAC') else: raise ValueError("Some problem with adjoint sources.") return measurements
window_params['win_overlap'] = False window_params['wtype'] = 'hann' window_params['causal_side'] = False window_params['plot'] = False # ********************************************* # ********************************************* # only for testing the test: # def l2_simple(tr_1,tr_2): # mf = np.sum(0.5 * (tr_1.data - tr_2.data) **2) # adstf = (tr_1.data - tr_2.data) # return mf,adstf m_a_options = {'g_speed':g_speed,'window_params':window_params} m_func = rm.get_measure_func(mtype) a_func = af.get_adj_func(mtype) # create observed data, synthetics and perturbation c_obs = 2 * (np.random.rand(2401,) - 0.5) c_ini = 2 * (np.random.rand(2401,) - 0.5) d_c = 2 * (np.random.rand(2401,) - 0.5) # form traces (measurement script works with obspy trace objects, not pure arrays) c_obs = Trace(data=c_obs) c_obs.stats.sampling_rate = 1.0 c_obs.stats.sac = sacdict c_syn = Trace(data=c_ini) c_syn.stats.sampling_rate = 1.0 c_syn.stats.sac = sacdict
def adjointsrcs(source_config,mtype,step,ignore_network,bandpass, taper_perc,**options): """ Get 'adjoint source' from noise correlation data and synthetics. options: g_speed,window_params (only needed if mtype is ln_energy_ratio or enery_diff) """ files = [f for f in os.listdir(os.path.join(source_config['source_path'], 'observed_correlations')) ] files = [os.path.join(source_config['source_path'], 'observed_correlations',f) for f in files] step_n = 'step_{}'.format(int(step)) synth_dir = os.path.join(source_config['source_path'], step_n,'corr') adj_dir = os.path.join(source_config['source_path'], step_n,'adjt') if files == []: msg = 'No input found!' raise ValueError(msg) #i = 0 hws = options['window_params']['hw'][:] g_speed = options['g_speed'][:] with click.progressbar(files,label='Determining adjoint sources...') as bar: for f in bar: # read data try: tr_o = read(f)[0] except: print('\nCould not read data: '+os.path.basename(f)) #i+=1 continue # read synthetics try: synth_filename = get_synthetics_filename(os.path.basename(f), synth_dir,ignore_network=ignore_network) if synth_filename is None: continue #sname = glob(os.path.join(synth_dir,synth_filename))[0] print(synth_filename) tr_s = read(synth_filename)[0] except: print('\nCould not read synthetics: '+os.path.basename(f)) #i+=1 continue # Add essential metadata tr_s.stats.sac = get_essential_sacmeta(tr_o.stats.sac) # Check sampling rates. if round(tr_s.stats.sampling_rate,6) != round(tr_o.stats. sampling_rate,6): print("Sampling Rates (Hz):\n") print(tr_s.stats.sampling_rate) print(tr_o.stats.sampling_rate) msg = 'Sampling rates of data and synthetics must match.' raise ValueError(msg) func = af.get_adj_func(mtype) # ugly...sorry # Bandpasses for j in range(len(bandpass)): options['window_params']['hw'] = hws[j] options['g_speed'] = g_speed[j] tr_o_filt = tr_o.copy() tr_s_filt = tr_s.copy() # Waveforms must have same nr of samples. tr_s_filt.data = my_centered(tr_s_filt.data,tr_o.stats.npts) bp = bandpass[j] if bp != None: tr_o_filt.taper(taper_perc) tr_o_filt.filter('bandpass',freqmin=bp[0],freqmax=bp[1], corners=bp[2],zerophase=True) tr_s_filt.taper(taper_perc) tr_s_filt.filter('bandpass',freqmin=bp[0],freqmax=bp[1], corners=bp[2],zerophase=True) #====================================================== # Weight observed stack by nstack #====================================================== tr_o_filt.data /= tr_o_filt.stats.sac.user0 data, success = func(tr_o_filt,tr_s_filt,**options) if not success: continue adj_src = Stream() if isinstance(data,list): adj_src += Trace(data=data[0]) adj_src += Trace(data=data[1]) brnchs = ['c','a'] for k in range(2): adjtrc = adj_src[k] adjtrc.stats.sampling_rate = tr_s.stats.sampling_rate adjtrc.stats.sac = tr_s.stats.sac.copy() # Save the adjoint source file_adj_src = os.path.join(adj_dir, os.path.basename(synth_filename). rstrip('sac')+'{}.{}.sac'.format(brnchs[k],j)) adjtrc.write(file_adj_src,format='SAC') else: adj_src += Trace(data=data) for adjtrc in adj_src: adjtrc.stats.sampling_rate = tr_s.stats.sampling_rate adjtrc.stats.sac = tr_s.stats.sac.copy() # Save the adjoint source file_adj_src = os.path.join(adj_dir, os.path.basename(synth_filename). rstrip('sac')+'{}.sac'.format(j)) adjtrc.write(file_adj_src,format='SAC') return()
window_params['win_overlap'] = False window_params['wtype'] = 'hann' window_params['causal_side'] = False window_params['plot'] = False # ********************************************* # ********************************************* # only for testing the test: # def l2_simple(tr_1,tr_2): # mf = np.sum(0.5 * (tr_1.data - tr_2.data) **2) # adstf = (tr_1.data - tr_2.data) # return mf,adstf m_a_options = {'g_speed': g_speed, 'window_params': window_params} m_func = rm.get_measure_func(mtype) a_func = af.get_adj_func(mtype) # create observed data, synthetics and perturbation c_obs = 2 * (np.random.rand(2401, ) - 0.5) c_ini = 2 * (np.random.rand(2401, ) - 0.5) d_c = 2 * (np.random.rand(2401, ) - 0.5) # form traces (measurement script works with obspy trace objects, not pure arrays) c_obs = Trace(data=c_obs) c_obs.stats.sampling_rate = 1.0 c_obs.stats.sac = sacdict c_syn = Trace(data=c_ini) c_syn.stats.sampling_rate = 1.0 c_syn.stats.sac = sacdict #tr_taper_filter = Trace(data=np.ones(c_obs.stats.npts))
def adjointsrcs(source_config,mtype,step,ignore_network,**options): """ Get 'adjoint source' from noise correlation data and synthetics. options: g_speed,window_params (only needed if mtype is ln_energy_ratio or enery_diff) """ files = [f for f in os.listdir(os.path.join(source_config['source_path'], 'observed_correlations')) ] files = [os.path.join(source_config['source_path'], 'observed_correlations',f) for f in files] step_n = 'step_{}'.format(int(step)) synth_dir = os.path.join(source_config['source_path'], step_n,'corr') adj_dir = os.path.join(source_config['source_path'], step_n,'adjt') if files == []: msg = 'No input found!' raise ValueError(msg) #i = 0 with click.progressbar(files,label='Determining adjoint sources...') as bar: for f in bar: try: tr_o = read(f)[0] except: print('\nCould not read data: '+os.path.basename(f)) #i+=1 continue try: synth_filename = get_synthetics_filename(os.path.basename(f),synth_dir, ignore_network=ignore_network) if synth_filename is None: continue #sname = glob(os.path.join(synth_dir,synth_filename))[0] print(synth_filename) tr_s = read(synth_filename)[0] except: print('\nCould not read synthetics: '+os.path.basename(f)) #i+=1 continue # Add essential metadata tr_s.stats.sac = get_essential_sacmeta(tr_o.stats.sac) # Check sampling rates. if round(tr_s.stats.sampling_rate,6) != round(tr_o.stats.sampling_rate,6): print("Sampling Rates (Hz)") print(tr_s.stats.sampling_rate) print(tr_o.stats.sampling_rate) msg = 'Sampling rates of data and synthetics must match.' raise ValueError(msg) # Waveforms must have same nr of samples. tr_s.data = my_centered(tr_s.data,tr_o.stats.npts) # Get the adjoint source func = af.get_adj_func(mtype) data, success = func(tr_o,tr_s,**options) if not success: continue adj_src = Stream() if isinstance(data,list): adj_src += Trace(data=data[0]) adj_src += Trace(data=data[1]) # TODO: super ugly brnch = 'c' for adjtrc in adj_src: adjtrc.stats.sampling_rate = tr_s.stats.sampling_rate adjtrc.stats.sac = tr_s.stats.sac.copy() # Save the adjoint source file_adj_src = os.path.join(adj_dir, os.path.basename(synth_filename). rstrip('sac')+'{}.sac'.format(brnch)) print(file_adj_src) adjtrc.write(file_adj_src,format='SAC') brnch = 'a' else: adj_src += Trace(data=data) for adjtrc in adj_src: adjtrc.stats.sampling_rate = tr_s.stats.sampling_rate adjtrc.stats.sac = tr_s.stats.sac.copy() # Save the adjoint source file_adj_src = os.path.join(adj_dir, os.path.basename(synth_filename)) adjtrc.write(file_adj_src,format='SAC')
def adjointsrcs(source_config, mtype, step, ignore_network, bandpass, taper_perc, **options): """ Get 'adjoint source' from noise correlation data and synthetics. options: g_speed,window_params (only needed if mtype is ln_energy_ratio or enery_diff) """ files = [ f for f in os.listdir( os.path.join(source_config['source_path'], 'observed_correlations')) ] files = [ os.path.join(source_config['source_path'], 'observed_correlations', f) for f in files ] step_n = 'step_{}'.format(int(step)) synth_dir = os.path.join(source_config['source_path'], step_n, 'corr') adj_dir = os.path.join(source_config['source_path'], step_n, 'adjt') if files == []: msg = 'No input found!' raise ValueError(msg) #i = 0 hws = options['window_params']['hw'][:] g_speed = options['g_speed'][:] with click.progressbar(files, label='Determining adjoint sources...') as bar: for f in bar: # read data try: tr_o = read(f)[0] except: print('\nCould not read data: ' + os.path.basename(f)) #i+=1 continue # read synthetics try: synth_filename = get_synthetics_filename( os.path.basename(f), synth_dir, ignore_network=ignore_network) if synth_filename is None: continue #sname = glob(os.path.join(synth_dir,synth_filename))[0] print(synth_filename) tr_s = read(synth_filename)[0] except: print('\nCould not read synthetics: ' + os.path.basename(f)) #i+=1 continue # Add essential metadata tr_s.stats.sac = get_essential_sacmeta(tr_o.stats.sac) # Check sampling rates. if round(tr_s.stats.sampling_rate, 6) != round( tr_o.stats.sampling_rate, 6): print("Sampling Rates (Hz):\n") print(tr_s.stats.sampling_rate) print(tr_o.stats.sampling_rate) msg = 'Sampling rates of data and synthetics must match.' raise ValueError(msg) func = af.get_adj_func(mtype) # ugly...sorry # Bandpasses for j in range(len(bandpass)): options['window_params']['hw'] = hws[j] options['g_speed'] = g_speed[j] tr_o_filt = tr_o.copy() tr_s_filt = tr_s.copy() # Waveforms must have same nr of samples. tr_s_filt.data = my_centered(tr_s_filt.data, tr_o.stats.npts) bp = bandpass[j] if bp != None: tr_o_filt.taper(taper_perc) tr_o_filt.filter('bandpass', freqmin=bp[0], freqmax=bp[1], corners=bp[2], zerophase=True) tr_s_filt.taper(taper_perc) tr_s_filt.filter('bandpass', freqmin=bp[0], freqmax=bp[1], corners=bp[2], zerophase=True) #====================================================== # Weight observed stack by nstack #====================================================== tr_o_filt.data /= tr_o_filt.stats.sac.user0 data, success = func(tr_o_filt, tr_s_filt, **options) if not success: continue adj_src = Stream() if isinstance(data, list): adj_src += Trace(data=data[0]) adj_src += Trace(data=data[1]) brnchs = ['c', 'a'] for k in range(2): adjtrc = adj_src[k] adjtrc.stats.sampling_rate = tr_s.stats.sampling_rate adjtrc.stats.sac = tr_s.stats.sac.copy() # Save the adjoint source file_adj_src = os.path.join( adj_dir, os.path.basename(synth_filename).rstrip('sac') + '{}.{}.sac'.format(brnchs[k], j)) adjtrc.write(file_adj_src, format='SAC') else: adj_src += Trace(data=data) for adjtrc in adj_src: adjtrc.stats.sampling_rate = tr_s.stats.sampling_rate adjtrc.stats.sac = tr_s.stats.sac.copy() # Save the adjoint source file_adj_src = os.path.join( adj_dir, os.path.basename(synth_filename).rstrip('sac') + '{}.sac'.format(j)) adjtrc.write(file_adj_src, format='SAC') return ()