Пример #1
0
def test_update():
    # copy data
    os.mkdir('test/testdata/testsrc/step_0/corr')
    os.mkdir('test/testdata/testsrc/step_0/grad')

    os.system(
        'cp test/testdata/testsrc/step_0/corr_archived/NET.STA1..CHA--NET.STA2..CHA.sac \
		test/testdata/testsrc/step_0/corr/NET.STA1..CHA--NET.STA2..CHA.sac')

    os.system('cp test/testdata/testsrc/step_0/grad_archived/grad_all.npy\
		test/testdata/testsrc/step_0/grad/grad_all.npy')
    os.system('cp test/testdata/testsrc/step_0/starting_model_archived.h5\
		test/testdata/testsrc/step_0/starting_model.h5')
    os.system(
        'cp test/testdata/testsrc/step_0/ln_energy_ratio.measurement_archived.csv\
		test/testdata/testsrc/step_0/ln_energy_ratio.0.measurement.csv')

    # run forward model
    os.system('./test/testdata/testsrc/update.sh')

    # assert the results are the same
    # ToDo: path
    n1 = NoiseSource('test/testdata/testsrc/step_1_archived/starting_model.h5')
    n2 = NoiseSource('test/testdata/testsrc/step_1/starting_model.h5')

    assert (n1.distr_basis == n2.distr_basis).sum() == len(
        n1.distr_basis[0, :])

    # remove stuff
    os.system('rm -rf test/testdata/testsrc/step_0/grad')
    os.system('rm -rf test/testdata/testsrc/step_0/corr')
    os.system('rm -rf test/testdata/testsrc/step_1')
    os.system('rm test/testdata/testsrc/step_0/starting_model.h5')
    os.system(
        'rm test/testdata/testsrc/step_0/ln_energy_ratio.0.measurement.csv')
Пример #2
0
def test_sensitivity_kernel():
    class args(object):
        def __init__(self):
            self.source_model = os.path.join('test', 'testdata_v1',
                                             'testsource_v1')
            self.step = 0
            self.steplengthrun = False,
            self.ignore_network = True

    args = args()
    all_config = config_params(args, comm, size, rank)
    ns = get_ns(all_config)
    p = define_kernel_tasks(all_config, comm, size, rank)
    assert len(p[0]) == 3
    assert p[0][2][1].split()[-1] == 'STA2'

    input_files = input_files_kernel(p[0][1], all_config)

    nsrc = os.path.join('test', 'testdata_v1', 'testsource_v1',
                        'spectral_model.h5')
    output_file = "test"
    # use a one-sided taper: The seismogram probably has a non-zero end,
    # being cut off wherever the solver stopped running.
    taper = cosine_taper(ns[0], p=0.01)
    taper[0:ns[0] // 2] = 1.0
    kernel = compute_kernel(input_files[0], output_file, all_config,
                            NoiseSource(nsrc), ns, taper)
    np.save("newtestkernel.npy", kernel)
    saved_kernel = np.load(
        os.path.join('test', 'testdata_v1', 'testdata',
                     'NET.STA1..MXZ--NET.STA2..MXZ.0.npy'))
    assert np.allclose(kernel / kernel.max(),
                       saved_kernel / saved_kernel.max())
Пример #3
0
def test_forward_model():
    class args(object):
        def __init__(self):
            self.source_model = os.path.join('test', 'testdata_v1',
                                             'testsource_v1')
            self.step = 0
            self.steplengthrun = False,
            self.ignore_network = True

    args = args()
    all_config = config_params(args, comm, size, rank)
    assert all_config.auto_corr

    ns = get_ns(all_config)
    assert (ns[0] == 3600)
    assert (ns[1] == 7200)

    p = define_correlationpairs(all_config.source_config['project_path'],
                                all_config.auto_corr)
    assert len(p) == 3
    assert p[0][0].split()[-1] == 'STA1'

    input_files = add_input_files(p[1], all_config)[0]
    assert os.path.basename(input_files[0]) == 'NET.STA1..MXZ.h5'

    nsrc = os.path.join('test', 'testdata_v1', 'testsource_v1', 'iteration_0',
                        'starting_model.h5')
    # use a one-sided taper: The seismogram probably has a non-zero end,
    # being cut off wherever the solver stopped running.
    taper = cosine_taper(ns[0], p=0.01)
    taper[0:ns[0] // 2] = 1.0
    correlation, sta1, sta2 = compute_correlation(input_files, all_config,
                                                  NoiseSource(nsrc), ns, taper)
    corr_saved = np.load(
        os.path.join('test', 'testdata_v1', 'testdata',
                     'NET.STA1..MXZ--NET.STA2..MXZ.npy'))

    assert np.allclose(correlation, corr_saved)
Пример #4
0
def g1g2_kern(wf1str, wf2str, kernel, adjt, src, source_conf, insta):

    measr_conf = json.load(
        open(os.path.join(source_conf['source_path'], 'measr_config.json')))

    bandpass = measr_conf['bandpass']

    if bandpass == None:
        filtcnt = 1
    elif type(bandpass) == list:
        if type(bandpass[0]) != list:
            filtcnt = 1
        else:
            filtcnt = len(bandpass)

    ntime, n, n_corr, Fs = get_ns(wf1str, source_conf, insta)
    # use a one-sided taper: The seismogram probably has a non-zero end,
    # being cut off whereever the solver stopped running.
    taper = cosine_taper(ntime, p=0.01)
    taper[0:ntime // 2] = 1.0

    ########################################################################
    # Prepare filenames and adjoint sources
    ########################################################################

    filenames = []
    adjt_srcs = []
    adjt_srcs_cnt = 0

    for ix_f in range(filtcnt):

        filename = kernel + '.{}.npy'.format(ix_f)
        filenames.append(filename)
        #if os.path.exists(filename):
        #   continue

        f = Stream()
        for a in adjt:
            adjtfile = a + '*.{}.sac'.format(ix_f)
            adjtfile = glob(adjtfile)
            try:
                f += read(adjtfile[0])[0]
                f[-1].data = my_centered(f[-1].data, n_corr)
                adjt_srcs_cnt += 1
            except IndexError:
                print('No adjoint source found: {}\n'.format(a))
                break

        adjt_srcs.append(f)


########################################################################
# Compute the kernels
########################################################################

    with NoiseSource(src) as nsrc:

        ntraces = nsrc.src_loc[0].shape[0]

        if insta:
            # open database
            dbpath = json.load(
                open(os.path.join(source_conf['project_path'],
                                  'config.json')))['wavefield_path']
            # open and determine Fs, nt
            db = instaseis.open_db(dbpath)
            # get receiver locations
            lat1 = geograph_to_geocent(float(wf1[2]))
            lon1 = float(wf1[3])
            rec1 = instaseis.Receiver(latitude=lat1, longitude=lon1)
            lat2 = geograph_to_geocent(float(wf2[2]))
            lon2 = float(wf2[3])
            rec2 = instaseis.Receiver(latitude=lat2, longitude=lon2)

        else:
            wf1 = WaveField(wf1str)
            wf2 = WaveField(wf2str)

        kern = np.zeros((filtcnt, ntraces, len(adjt)))

        ########################################################################
        # Loop over locations
        ########################################################################
        for i in range(ntraces):

            # noise source spectrum at this location
            # For the kernel, this contains only the basis functions of the
            # spectrum without weights; might still be location-dependent,
            # for example when constraining sensivity to ocean
            S = nsrc.get_spect(i)

            if S.sum() == 0.:
                # The spectrum has 0 phase so only checking absolute value here
                continue

            ####################################################################
            # Get synthetics
            ####################################################################
            if insta:
                # get source locations
                lat_src = geograph_to_geocent(nsrc.src_loc[1, i])
                lon_src = nsrc.src_loc[0, i]
                fsrc = instaseis.ForceSource(latitude=lat_src,
                                             longitude=lon_src,
                                             f_r=1.e12)

                s1 = np.ascontiguousarray(
                    db.get_seismograms(
                        source=fsrc,
                        receiver=rec1,
                        dt=1. / source_conf['sampling_rate'])[0].data * taper)
                s2 = np.ascontiguousarray(
                    db.get_seismograms(
                        source=fsrc,
                        receiver=rec2,
                        dt=1. / source_conf['sampling_rate'])[0].data * taper)

            else:
                s1 = np.ascontiguousarray(wf1.data[i, :] * taper)
                s2 = np.ascontiguousarray(wf2.data[i, :] * taper)

            spec1 = np.fft.rfft(s1, n)
            spec2 = np.fft.rfft(s2, n)

            g1g2_tr = np.multiply(np.conjugate(spec1), spec2)
            c = np.multiply(g1g2_tr, S)

            #######################################################################
            # Get Kernel at that location
            #######################################################################
            corr_temp = my_centered(np.fft.ifftshift(np.fft.irfft(c, n)),
                                    n_corr)

            #######################################################################
            # Apply the 'adjoint source'
            #######################################################################
            for ix_f in range(filtcnt):
                f = adjt_srcs[ix_f]

                if f == None:
                    continue
                for j in range(len(f)):
                    delta = f[j].stats.delta

                    kern[ix_f, i, j] = np.dot(corr_temp, f[j].data) * delta

                    #elif measr_conf['mtype'] in ['envelope']:
                    #    if j == 0:
                    #        corr_temp_h = corr_temp
                    #        print(corr_temp_h)
                    #    if j == 1:
                    #        corr_temp_h = hilbert(corr_temp)
                    #        print(corr_temp_h)
                    #
                    #    kern[ix_f,i,j] = np.dot(corr_temp,f[j].data) * delta

            if i % 50000 == 0:
                print("Finished {} source locations.".format(i))

    if not insta:
        wf1.file.close()
        wf2.file.close()

    for ix_f in range(filtcnt):
        filename = filenames[ix_f]
        if kern[ix_f, :, :].sum() != 0:
            np.save(filename, kern[ix_f, :, :])
    return ()
Пример #5
0
def run_corr(args, comm, size, rank):

    all_conf = config_params(args, comm, size, rank)
    # Distributing the tasks
    correlation_tasks, n_p_p, n_p = define_correlation_tasks(all_conf,
                                                             comm, size, rank)
    if len(correlation_tasks) == 0:
        return()
    if all_conf.config['verbose']:
        print('Rank number %g' % rank)
        print('working on pair nr. %g to %g of %g.' % (rank * n_p_p,
                                                       rank * n_p_p +
                                                       n_p_p, n_p))

    # Current model for the noise source
    it_dir = os.path.join(all_conf.source_config['project_path'],
                        all_conf.source_config['source_name'],
                        'iteration_' + str(all_conf.step))
    nsrc = os.path.join(it_dir,'starting_model.h5')

    # Smart numbers
    all_ns = get_ns(all_conf)  # ntime, n, n_corr, Fs

    # use a one-sided taper: The seismogram probably has a non-zero end,
    # being cut off wherever the solver stopped running.
    taper = cosine_taper(all_ns[0], p=0.01)
    taper[0: all_ns[0] // 2] = 1.0

    with NoiseSource(nsrc) as nsrc:
        for cp in correlation_tasks:
            try:
                input_files_list = add_input_files(cp, all_conf)

                output_files = add_output_files(cp, all_conf)
            except (IndexError, FileNotFoundError):
                if all_conf.config['verbose']:
                    print('Could not determine correlation for: %s\
    \nCheck if wavefield .h5 file is available.' % cp)
                continue

            if type(input_files_list[0]) != list:
                input_files_list = [input_files_list]

            for i, input_files in enumerate(input_files_list):
                correlation, sta1, sta2 = compute_correlation(input_files,
                                                              all_conf, nsrc,
                                                              all_ns, taper)
                add_metadata_and_write(correlation, sta1, sta2,
                                       output_files[i], all_ns[3])

            if all_conf.source_config["rotate_horizontal_components"]:
                fls = glob(os.path.join(it_dir, "corr", "*{}*{}*.sac".format(cp[0].split()[1],
                                                                            cp[1].split()[1])))
                fls.sort()
                apply_rotation(fls,
                               stationlistfile=os.path.join(all_conf.source_config['project_path'],
                               "stationlist.csv"), output_directory=os.path.join(it_dir, "corr"))

    comm.barrier()
    if rank == 0:
        if all_conf.source_config["rotate_horizontal_components"]:
            fls_to_remove = glob(os.path.join(it_dir, "corr", "*MX[E,N]*MX[E,N]*.sac"))
            fls_to_remove.extend(glob(os.path.join(it_dir, "corr", "*MX[E,N]*MXZ*.sac")))
            fls_to_remove.extend(glob(os.path.join(it_dir, "corr", "*MXZ*MX[E,N]*.sac")))
            for f in fls_to_remove:
                os.system("rm " + f)


    return()
Пример #6
0
                                         'testsource_v1')
        self.step = 0
        self.steplengthrun = False,
        self.ignore_network = True


args = args()
all_config = config_params(args, comm, size, rank)
m_a_options = {'g_speed': g_speed, 'window_params': window_params}
m_func = rm.get_measure_func(mtype)
all_ns = get_ns(all_config)
ntime, n, n_corr, Fs = all_ns
taper = cosine_taper(ntime, p=0.01)
taper[0:ntime // 2] = 1.0

with NoiseSource(source_file) as n:
    surf_area = n.surf_area

# sum the dimension that relates to filters
grad = grad.sum(axis=1)

# apply surface elements for integration
for j in range(grad.shape[0]):
    grad[j, :, 0] *= surf_area

# measurement
obs = read(obsfile)[0]
syn = read(synfile)[0]
syn.stats.sac = {}
syn.stats.sac['dist'] = obs.stats.sac['dist']
msr_o = m_func(obs, **m_a_options)
Пример #7
0
def run_kern(args, comm, size, rank):

    args.steplengthrun = False  # by default
    all_conf = config_params(args, comm, size, rank)

    kernel_tasks, n_p_p, n_p = define_kernel_tasks(all_conf, comm, size, rank)
    if len(kernel_tasks) == 0:
        return ()
    if all_conf.config['verbose']:
        print('Rank number %g' % rank)
        print('working on pair nr. %g to %g of %g.' %
              (rank * n_p_p, rank * n_p_p + n_p_p, n_p))

    # Current model for the noise source
    nsrc = os.path.join(all_conf.source_config['project_path'],
                        all_conf.source_config['source_name'],
                        'spectral_model.h5')

    # Smart numbers
    all_ns = get_ns(all_conf)  # ntime, n, n_corr, Fs

    # use a one-sided taper: The seismogram probably has a non-zero end,
    # being cut off wherever the solver stopped running.
    taper = cosine_taper(all_ns[0], p=0.01)
    taper[0:all_ns[0] // 2] = 1.0

    with NoiseSource(nsrc) as nsrc:
        for kp in kernel_tasks:
            try:
                input_file_list = add_input_files(kp, all_conf)
                output_files = add_output_files(kp, all_conf)
            except (IOError, IndexError):
                if all_conf.config['verbose']:
                    print('Could not find input for: %s\
\nCheck if wavefield .h5 file and base_model file are available.' % kp)
                continue

            for i, input_files in enumerate(input_file_list):
                kern = compute_kernel(input_files, output_files[i], all_conf,
                                      nsrc, all_ns, taper)
                if kern is None:
                    continue

                for ix_f in range(all_conf.filtcnt):
                    if not all_conf.source_config[
                            "rotate_horizontal_components"]:
                        if kern[:, ix_f, :, :].sum() != 0:
                            filename = output_files[i] + '.{}.npy'.format(ix_f)
                            np.save(filename, kern[:, ix_f, :, :])
                        else:
                            continue

            # Rotation
        if all_conf.source_config["rotate_horizontal_components"]:
            for kp in kernel_tasks:
                try:
                    input_file_list = add_input_files(kp, all_conf)
                    output_files = add_output_files(kp, all_conf)

                except (IOError, IndexError):
                    continue

                output_files = [
                    re.sub("MXE", "MXT", of) for of in output_files
                ]
                output_files = [
                    re.sub("MXN", "MXR", of) for of in output_files
                ]
                # - get all the adjoint sources:
                # for all channels, all filter bands, both branches
                adjt_srcs = []
                for infile in input_file_list:
                    adjt_srcs.append(
                        open_adjoint_sources(all_conf, infile[2], all_ns[2]))
                # - open 9 temp files
                if all_conf.source_config["rotate_horizontal_components"]:
                    it_dir = os.path.join(
                        all_conf.source_config['project_path'],
                        all_conf.source_config['source_name'],
                        'iteration_' + str(all_conf.step))
                    tfname = os.path.join(
                        it_dir, "kern",
                        "*{}*{}*_temp".format(kp[0].split()[1].strip(),
                                              kp[1].split()[1].strip()))
                    kern_temp_files = glob(tfname)
                    if kern_temp_files == []:
                        continue

                    kern_temp_files.sort()
                    if len(kern_temp_files) == 9:
                        assemble_rotated_kernel(
                            kern_temp_files, output_files, adjt_srcs,
                            os.path.join(
                                all_conf.source_config["project_path"],
                                "stationlist.csv"))
    return ()
# =============================================================================
# initialize stuff

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

global itargs
itargs = iteration_args()

if do_not_print_warnings:
    warnings.filterwarnings("ignore")
# read the starting model
model_file_name = os.path.join(itargs.iteration, 'starting_model.h5')
os.system('cp ' + model_file_name + ' starting_model_iteration_0.h5')
with NoiseSource(model_file_name) as n0:
    # rearrange as 1-D array
    model_shape = n0.distr_basis.shape
    print("model shape ", model_shape)
    x0 = n0.distr_basis[:].ravel()
    x_ref = x0.copy()

# call the optimization
result = minimize(objective_function,
                  x0=x0,
                  args=(model_shape, weights, regularization, smoothing_params,
                        x_ref, comm, size, rank, itargs),
                  method=optimization_scheme,
                  bounds=bounds,
                  jac=jacobian,
                  tol=tol,
Пример #9
0
def g1g2_kern(wf1, wf2, corr_file, kernel, adjt, src, source_conf, scale=1.0):

    #ToDo: Take care of saving metainformation
    #ToDo: Think about how to manage different types of sources (numpy array vs. get from configuration -- i.e. read source from file as option)
    #ToDo: check whether to include autocorrs from user (now hardcoded off)
    #ToDo: Parallel loop(s)
    #ToDo tests

    ntime, n, n_corr = get_ns(wf1, source_conf)

    taper = cosine_taper(ntime, p=0.05)

    with WaveField(wf1) as wf1, WaveField(wf2) as wf2:

        if wf1.stats['Fs'] != wf2.stats['Fs']:
            msg = 'Sampling rates of synthetic green\'s functions must match.'
            raise ValueError(msg)

        # initialize new hdf5 files for correlation and green's function correlation
        #with wf1.copy_setup(corr_file,nt=n_corr) as correl, NoiseSource(src) as nsrc:
        #with wf1.copy_setup(corr_file,nt=n_corr) as correl:

        with NoiseSource(src) as nsrc:

            correlation = np.zeros(n_corr)

            kern = np.zeros(wf1.stats['ntraces'])

            # Try to use a trick: Use causal and acausal part of f separately.
            f = read(adjt)[0]
            f.data = my_centered(f.data, n_corr)

            n_acausal_samples = (f.stats.npts - 1) / 2
            specf = np.fft.rfft(f[n_acausal_samples:], n)

            # Loop over source locations
            #with click.progressbar(range(wf1.stats['ntraces']),\
            #label='Correlating...' ) as ind:
            for i in range(wf1.stats['ntraces']):

                #print(i)
                s1 = np.ascontiguousarray(wf1.data[i, :] * taper) * scale
                #print(s1.sum())
                spec1 = np.fft.rfft(s1, n)
                #print(spec1.sum())
                T = np.multiply(np.conj(spec1), nsrc.get_spect(i))
                # plt.plot(np.abs(spec1)/np.max(np.abs(spec1)))
                # plt.plot(np.abs(T)/np.max(np.abs(T)))
                # plt.show()

                # it would be cleaner to use ifftshift here!
                T = np.fft.ifftshift(np.fft.irfft(T,
                                                  n))[0:len(s1)]  #[-len(s1):]
                # if i in [1,2,3,4,5]:
                #     plt.plot(T[::-1]/np.max(np.abs(T)))
                #     plt.plot(s1/np.max(np.abs(s1)),'--')
                #     plt.show()
                # Get s2 in the shape of f
                # we need to add half of the length of f before G to replace the
                # acausal part that G does not have to start with:

                #s2 = np.zeros(n)
                s2 = np.ascontiguousarray(wf2.data[i, :] * taper) * scale
                #print(s2.sum())
                #s2[n_acausal_samples:n_acausal_samples+ntime] = s2_caus
                spec2 = np.fft.rfft(s2, n)
                # plt.plot(s2_caus/np.max(np.abs(s2_caus)))
                # plt.plot(f.data/np.max(np.abs(f.data)))
                # plt.plot(s2/np.max(np.abs(s2)))
                # plt.plot(n_acausal_samples,0.5,'rd')

                # plt.show()

                # transform both f and s2 to fourier d
                # (again, zeropadding but just to avoid circular convolution)

                # plt.plot(np.abs(spec2)/np.max(np.abs(spec2)))
                # plt.plot(np.abs(specf)/np.max(np.abs(specf)))
                # plt.show()
                g2f_tr = np.multiply(np.conj(spec2), specf)
                #print(specf.sum())
                #plt.plot(n_acausal_samples,0.5,'rd')
                #plt.plot(n,0.5,'gd')

                # it would be cleaner to use ifftshift here!
                u_dagger = np.fft.ifftshift(np.fft.irfft(
                    g2f_tr, n))[0:len(s1)]  #[-len(s1):]
                # plt.plot(u_dagger/np.max(np.abs(u_dagger)))
                # plt.plot(T/np.max(np.abs(T)))

                # plt.show()

                # The frequency spectrum of the noise source is included here
                ## corr_temp = my_centered(np.fft.ifftshift(np.fft.irfft(c,n)),n_corr)
                # A Riemann sum -- one could actually build in a more fancy integration here
                #print(f.stats.delta)
                kern[i] = np.dot(u_dagger, T) * f.stats.delta
                #print(kern[i])

                if i % 50000 == 0:
                    print("Finished {} source locations.".format(i))

                #np.save(kernel,kern)
            return (kern)
Пример #10
0
def g1g2_corr(wf1, wf2, corr_file, kernel, adjt, src, source_conf, kernelrun):

    #ToDo: Take care of saving metainformation
    #ToDo: Think about how to manage different types of sources (numpy array vs. get from configuration -- i.e. read source from file as option)
    #ToDo: check whether to include autocorrs from user (now hardcoded off)
    #ToDo: Parallel loop(s)
    #ToDo tests

    ntime, n, n_corr = get_ns(wf1, source_conf)

    taper = cosine_taper(ntime, p=0.05)

    with WaveField(wf1) as wf1, WaveField(wf2) as wf2:

        if wf1.stats['Fs'] != wf2.stats['Fs']:
            msg = 'Sampling rates of synthetic green\'s functions must match.'
            raise ValueError(msg)

        # initialize new hdf5 files for correlation and green's function correlation
        #with wf1.copy_setup(corr_file,nt=n_corr) as correl, NoiseSource(src) as nsrc:
        #with wf1.copy_setup(corr_file,nt=n_corr) as correl:

        with NoiseSource(src) as nsrc:

            correlation = np.zeros(n_corr)

            if kernelrun:

                #if not os.path.exists(adjt):
                #    print('Adjoint source %s not found, skipping kernel.')
                #    return()

                kern = np.zeros((wf1.stats['ntraces'], len(adjt)))

                f = Stream()
                for adjtfile in adjt:
                    if adjtfile == '-':
                        return
                    f += read(adjtfile)[0]
                    f[-1].data = my_centered(f[-1].data, n_corr)

            # Loop over source locations
            #with click.progressbar(range(wf1.stats['ntraces']),\
            #label='Correlating...' ) as ind:
            for i in range(wf1.stats['ntraces']):

                # noise source spectrum at this location
                # if calculating kernel, the spectrum is location independent.
                S = nsrc.get_spect(i)

                if S.sum() == 0.:  # The spectrum has 0 phase anyway
                    continue

                s1 = np.ascontiguousarray(wf1.data[i, :] * taper)
                s2 = np.ascontiguousarray(wf2.data[i, :] * taper)

                spec1 = np.fft.rfft(s1, n)
                spec2 = np.fft.rfft(s2, n)

                g1g2_tr = np.multiply(np.conjugate(spec1), spec2)
                # if i%50000 == 0:
                #     print(g1g2_tr[0:10],file=None)
                #     print(g1g2_tr.max(),file=None)

                c = np.multiply(g1g2_tr, S)

                # if i%50000==0:
                #     print(c[0:10],file=None)
                #     print(c.max(),file=None)

                if kernelrun:

                    corr_temp = my_centered(
                        np.fft.ifftshift(np.fft.irfft(c, n)), n_corr)
                    ##if i%50000 == 0:
                    #    ##print(corr_temp[0:10],file=None)
                    #print(corr_temp.max(),file=None)
                    # A Riemann sum
                    for j in range(len(adjt)):
                        kern[i, j] = np.dot(corr_temp,
                                            f[j].data) * f[j].stats.delta

                else:

                    correlation += my_centered(
                        np.fft.ifftshift(np.fft.irfft(c, n)), n_corr)

                if i % 50000 == 0:
                    print("Finished {} source locations.".format(i))

        if kernelrun:
            np.save(kernel, kern)

        else:
            trace = Trace()
            trace.stats.sampling_rate = wf1.stats['Fs']
            trace.data = correlation
            trace.write(filename=corr_file, format='SAC')
Пример #11
0
def assemble_ascent_dir(source_model,step,snr_min,n_min,save_all=False,
	normalize_gradient=False):

# where is the measurement database located?
	source_config=json.load(open(source_model))
	datadir = os.path.join(source_config['source_path'],'step_' + str(step))
	outfile	= os.path.join(datadir,'grad','grad_info.txt')
	if os.path.exists(outfile):
		os.system('rm '+outfile)

# Figure out how many spectral basis functions there are:
	with NoiseSource(os.path.join(datadir,'starting_model.h5')) as nsrc:
		n_basis = nsrc.spect_basis.shape[0]


# allocate the kernel array
	grd = np.load(os.path.join(source_config['project_path'],'sourcegrid.npy'))

	gradient = np.zeros((n_basis,np.shape(grd)[1]))

# get the predefined weights
	measr_config = json.load(open(os.path.join(source_config['source_path'],\
		'measr_config.json')))
	m_type = measr_config['mtype']
	try:
		var_weights = measr_config['weights']
	except KeyError:
		var_weights = np.ones(n_basis)


# Loop over basis functions

	for ix_basis in range(n_basis):

		msrfile = os.path.join(datadir,"{}.{}.measurement.csv".\
			format(measr_config['mtype'],ix_basis))



	# Read in the csv files of measurement.

		data = pd.read_csv(msrfile)


	# loop over stationpairs

		cnt_success = 0
		cnt_lowsnr = 0
		cnt_lown = 0
		cnt_overlap = 0
		cnt_unavail = 0
		n = len(data)
		print('Nr Measurements:')
		print(n)
		print('*'*16)

		for i in range(n):

			if data.at[i,'snr'] < snr_min and data.at[i,'snr_a'] < snr_min:
				cnt_lowsnr += 1
				continue

			if data.at[i,'nstack'] < n_min:
				cnt_lown += 1
				continue


	# ToDo: deal with station pairs with several measurements (with different instruments)
	# (At the moment, just all added. Probably fine on this large scale)
	# find kernel file
			sta1 = data.at[i,'sta1']
			sta2 = data.at[i,'sta2']
		
			#if sta1.split('.')[-1][-1] in ['E','N','T','R']:
		#		msg = "Cannot yet handle horizontal components"
	#			raise NotImplementedError(msg)
	#		if sta2.split('.')[-1][-1] in ['E','N','T','R']:
	#			msg = "Cannot yet handle horizontal components"
	#			raise NotImplementedError(msg)
		
		
	# ToDo !!! Replace this by a decent formulation, where the channel is properly set !!! No error for E, R, T, N
			sta1 = "*.{}..{}".format(sta1.split('.')[1],source_config['channel']) # ignoring network: IRIS has sometimes several network codes at same station
			sta2 = "*.{}..{}".format(sta2.split('.')[1],source_config['channel']) # ignoring network: IRIS has sometimes several network codes at same station
		
			kernelfile1 = os.path.join(datadir,'kern',"{}--{}.{}.npy".format(sta1,sta2,ix_basis))
			kernelfile2 = os.path.join(datadir,'kern',"{}--{}.{}.npy".format(sta2,sta1,ix_basis))
			# Same problem with different network codes.
			# Due to station pairs being in alphabetic order of network.station.loc.cha, different network
			# codes also lead to different ordering.
			try:
				kernelfile = glob(kernelfile1)[0]
			except IndexError:
				try: 
					kernelfile = glob(kernelfile2)[0]
				except IndexError:
					kernelfile = kernelfile1 
					# Check that first, and then complain.




	# Skip if entry is nan: This is most likely due to no measurement taken because station distance too short	
			if (isnan(data.at[i,'obs']) and m_type 
				in ['ln_energy_ratio','energy_diff']):
				print("No measurement in dataset for:")
				print(os.path.basename(kernelfile))
				cnt_overlap += 1
				continue

	# ...unless somehow the kernel went missing (undesirable case!)

			if not os.path.exists(kernelfile):
				print("File does not exist:")
				print(os.path.basename(kernelfile))
				cnt_unavail += 1
				continue


	# load kernel
			kernel = np.load(kernelfile)
			if True in np.isnan(kernel):
				print("kernel contains nan, skipping")
				print(os.path.basename(kernelfile))
				continue


	# multiply kernel and measurement, add to descent dir.
	# always assuming L2 norm here!
		
			else:

				if kernel.shape[-1] == 1:

					kernel = kernel[:,0]

					if m_type in ['ln_energy_ratio','energy_diff']:
						kernel *= (data.at[i,'syn'] - data.at[i,'obs'])
					

				elif kernel.shape[-1] == 2:
					if m_type in ['ln_energy_ratio','energy_diff']:
						kernel[:,0] *= (data.at[i,'syn'] - data.at[i,'obs'])
						kernel[:,1] *= (data.at[i,'syn_a'] - data.at[i,'obs_a'])
						kernel = kernel[:,0] + kernel[:,1]
					#if m_type in ['envelope']:
				#		kernel = kernel[:,0] + kernel[:,1]
				cnt_success += 1 # yuhu

			
	
			
		# collect
			gradient[ix_basis,:] += kernel * var_weights[ix_basis]
			del kernel

# save
	if save_all:
		warn('This option is discontinued, because all the single kernels are\
			available in the kern/ directory.')


	if normalize_gradient:
		gradient /= np.abs(gradient).max()
	
	kernelfile = os.path.join(datadir,'grad','grad_all.npy')
	np.save(kernelfile,gradient)

	# output metadata
		
	with open(outfile,'a') as fh:

		fh.write('Analyzed %g station pairs of %g successfully.\n' %(cnt_success,n))
		fh.write('No data found for %g station pairs.\n' %cnt_unavail)
		fh.write('No measurement taken for %g station pairs due to short interstation distance.\n' %cnt_overlap) 
		fh.write('Signal to noise ratio below threshold for %g station pairs.\n' %cnt_lowsnr)
		fh.write('Number of staacked windows below threshold for %g station pairs.\n' %cnt_lown)
		fh.write('\nParameters:==============================================================\n')
		fh.write('Source dir: %s \n' %source_model)
		fh.write('Step: %g' %int(step))
		fh.write('Minimum SNR: %g' %snr_min)
		fh.write('Minimum stack length: %g' %int(n_min))
		fh.write('Save all interstation gradients: %s' %str(save_all))
		fh.write('\n=========================================================================\n')
		fh.write('Project:\n')
		# append configurations
		cfg = open(os.path.join(source_config['project_path'],'config.json')).read()
		fh.write(cfg)
		fh.write('\n=========================================================================\n')
		fh.write('Source model:\n')
		fh.write(json.dumps(source_config))
		fh.write('\n=========================================================================\n')
		fh.write('Measurement:\n')
		cfg = open(os.path.join(source_config['source_path'],'measr_config.json')).read()
		fh.write(cfg)
Пример #12
0
def g1g2_corr(wf1, wf2, corr_file, src, source_conf, insta):
    """
    Compute noise cross-correlations from two .h5 'wavefield' files.
    Noise source distribution and spectrum is given by starting_model.h5
    It is assumed that noise sources are delta-correlated in space.
    """

    #ToDo: check whether to include autocorrs from user (now hardcoded off)
    #ToDo: Parallel loop(s)
    #ToDo tests

    # Metainformation: Include the reference station names for both stations
    # from wavefield files, if possible. Do not include geographic information
    # from .csv file as this might be error-prone. Just add the geographic
    # info later if needed.

    with NoiseSource(src) as nsrc:

        ntime, n, n_corr, Fs = get_ns(wf1, source_conf, insta)

        # use a one-sided taper: The seismogram probably has a non-zero end,
        # being cut off whereever the solver stopped running.
        taper = cosine_taper(ntime, p=0.01)
        taper[0:ntime // 2] = 1.0
        ntraces = nsrc.src_loc[0].shape[0]
        print(taper.shape)
        correlation = np.zeros(n_corr)

        if insta:
            # open database
            dbpath = json.load(
                open(os.path.join(source_conf['project_path'],
                                  'config.json')))['wavefield_path']
            # open and determine Fs, nt
            db = instaseis.open_db(dbpath)
            # get receiver locations
            lat1 = geograph_to_geocent(float(wf1[2]))
            lon1 = float(wf1[3])
            rec1 = instaseis.Receiver(latitude=lat1, longitude=lon1)
            lat2 = geograph_to_geocent(float(wf2[2]))
            lon2 = float(wf2[3])
            rec2 = instaseis.Receiver(latitude=lat2, longitude=lon2)

        else:
            wf1 = WaveField(wf1)
            wf2 = WaveField(wf2)

        # Loop over source locations
        for i in range(ntraces):

            # noise source spectrum at this location
            S = nsrc.get_spect(i)

            if S.sum() == 0.:
                #If amplitude is 0, continue. (Spectrum has 0 phase anyway. )
                continue

            if insta:
                # get source locations
                lat_src = geograph_to_geocent(nsrc.src_loc[1, i])
                lon_src = nsrc.src_loc[0, i]
                fsrc = instaseis.ForceSource(latitude=lat_src,
                                             longitude=lon_src,
                                             f_r=1.e12)

                s1 = np.ascontiguousarray(
                    db.get_seismograms(
                        source=fsrc,
                        receiver=rec1,
                        dt=1. / source_conf['sampling_rate'])[0].data * taper)
                s2 = np.ascontiguousarray(
                    db.get_seismograms(
                        source=fsrc,
                        receiver=rec2,
                        dt=1. / source_conf['sampling_rate'])[0].data * taper)

            else:
                # read Green's functions
                s1 = np.ascontiguousarray(wf1.data[i, :] * taper)
                s2 = np.ascontiguousarray(wf2.data[i, :] * taper)

            # Fourier transform for greater ease of convolution
            spec1 = np.fft.rfft(s1, n)
            spec2 = np.fft.rfft(s2, n)

            # convolve G1G2
            g1g2_tr = np.multiply(np.conjugate(spec1), spec2)

            # convolve noise source
            c = np.multiply(g1g2_tr, S)

            # transform back
            correlation += my_centered(np.fft.ifftshift(np.fft.irfft(c, n)),
                                       n_corr) * nsrc.surf_area[i]

            # occasional info
            if i % 50000 == 0:
                print("Finished {} source locations.".format(i))


###################### end of loop over all source locations ###################

        if not insta:
            wf1.file.close()
            wf2.file.close()

        # save output
        trace = Trace()
        trace.stats.sampling_rate = Fs
        trace.data = correlation
        # try to add some meta data
        try:
            sta1 = wf1.stats['reference_station']
            sta2 = wf2.stats['reference_station']
            trace.stats.station = sta1.split('.')[1]
            trace.stats.network = sta1.split('.')[0]
            trace.stats.location = sta1.split('.')[2]
            trace.stats.channel = sta1.split('.')[3]
            trace.stats.sac = {}
            trace.stats.sac['kuser0'] = sta2.split('.')[1]
            trace.stats.sac['kuser1'] = sta2.split('.')[0]
            trace.stats.sac['kuser2'] = sta2.split('.')[2]
            trace.stats.sac['kevnm'] = sta2.split('.')[3]
        except:
            pass

        trace.write(filename=corr_file, format='SAC')