Beispiel #1
0
    def test_qseis_vs_ahfull(self):
        random.seed(23)

        vp = 5.8 * km
        vs = 3.46 * km

        mod = cake.LayeredModel.from_scanlines(
            cake.read_nd_model_str('''
  0. %(vp)g %(vs)g 2.6 1264. 600.
 20. %(vp)g %(vs)g 2.6 1264. 600.'''.lstrip() % dict(vp=vp / km, vs=vs / km)))

        store_id_qseis = 'homogeneous_qseis'
        store_id_ahfull = 'homogeneous_ahfull'

        qsconf = qseis.QSeisConfig()
        qsconf.qseis_version = '2006a'

        textra = 5.0

        qsconf.time_region = (gf.meta.Timing('{vel:%g}-%g' %
                                             (vp / km, textra)),
                              gf.meta.Timing('{vel:%g}+%g' %
                                             (vs / km, textra)))

        qsconf.cut = (gf.meta.Timing('{vel:%g}-%g' % (vp / km, textra)),
                      gf.meta.Timing('{vel:%g}+%g' % (vs / km, textra)))

        qsconf.relevel_with_fade_in = True

        qsconf.fade = (gf.meta.Timing('{vel:%g}-%g' % (vp / km, textra)),
                       gf.meta.Timing('{vel:%g}-%g' % (vp / km, 0.)),
                       gf.meta.Timing('{vel:%g}+%g' % (vs / km, 0.)),
                       gf.meta.Timing('{vel:%g}+%g' % (vs / km, textra)))

        qsconf.wavelet_duration_samples = 0.001
        qsconf.sw_flat_earth_transform = 0
        qsconf.filter_surface_effects = 1
        qsconf.wavenumber_sampling = 5.
        qsconf.aliasing_suppression_factor = 0.01

        sample_rate = 10.

        config = gf.meta.ConfigTypeA(
            id=store_id_qseis,
            sample_rate=sample_rate,
            receiver_depth=0. * km,
            source_depth_min=1. * km,
            source_depth_max=19 * km,
            source_depth_delta=6. * km,
            distance_min=2. * km,
            distance_max=20 * km,
            distance_delta=2 * km,
            modelling_code_id='qseis.2006a',
            earthmodel_1d=mod,
            tabulated_phases=[
                gf.meta.TPDef(id='begin', definition='p,P,p\\,P\\'),
                gf.meta.TPDef(id='end', definition='s,S,s\\,S\\'),
            ])

        config.validate()

        store_dir_qseis = mkdtemp(prefix=store_id_qseis)
        self.tempdirs.append(store_dir_qseis)

        gf.store.Store.create_editables(store_dir_qseis,
                                        config=config,
                                        extra={'qseis': qsconf})

        store = gf.store.Store(store_dir_qseis, 'r')
        store.make_ttt()
        store.close()

        try:
            qseis.build(store_dir_qseis, nworkers=1)
        except qseis.QSeisError as e:
            if str(e).find('could not start qseis') != -1:
                logger.warn('qseis not installed; '
                            'skipping test_pyrocko_gf_vs_qseis')
                return
            else:
                raise

        config = gf.meta.ConfigTypeA(
            id=store_id_ahfull,
            sample_rate=sample_rate,
            receiver_depth=0. * km,
            source_depth_min=1. * km,
            source_depth_max=19 * km,
            source_depth_delta=6. * km,
            distance_min=2. * km,
            distance_max=20 * km,
            distance_delta=2 * km,
            modelling_code_id='ahfullgreen',
            earthmodel_1d=mod,
            tabulated_phases=[
                gf.meta.TPDef(id='begin', definition='p,P,p\\,P\\'),
                gf.meta.TPDef(id='end', definition='s,S,s\\,S\\'),
            ])

        config.validate()

        store_dir_ahfull = mkdtemp(prefix=store_id_qseis)
        self.tempdirs.append(store_dir_ahfull)

        gf.store.Store.create_editables(store_dir_ahfull, config=config)

        store = gf.store.Store(store_dir_ahfull, 'r')
        store.make_ttt()
        store.close()

        ahfullgreen.build(store_dir_ahfull, nworkers=1)

        sdepth = rand(config.source_depth_min, config.source_depth_max)
        sdepth = round(
            (sdepth - config.source_depth_min)
            / config.source_depth_delta) * config.source_depth_delta \
            + config.source_depth_min

        source = gf.MTSource(lat=0., lon=0., depth=sdepth)

        source.m6 = tuple(rand(-1., 1.) for x in range(6))

        for ii in range(5):
            azi = random.random() * 365.
            dist = rand(config.distance_min, config.distance_max)
            dist = round(dist / config.distance_delta) * config.distance_delta

            dnorth = dist * math.cos(azi * d2r)
            deast = dist * math.sin(azi * d2r)

            targets = []
            for cha in 'rtz':
                target = gf.Target(quantity='displacement',
                                   codes=('', '0000', 'PG', cha),
                                   north_shift=dnorth,
                                   east_shift=deast,
                                   depth=config.receiver_depth,
                                   store_id=store_id_ahfull)

                dist = source.distance_to(target)
                azi, bazi = source.azibazi_to(target)

                if cha == 'r':
                    target.azimuth = bazi + 180.
                    target.dip = 0.
                elif cha == 't':
                    target.azimuth = bazi - 90.
                    target.dip = 0.
                elif cha == 'z':
                    target.azimuth = 0.
                    target.dip = 90.

                targets.append(target)

            runner = qseis.QSeisRunner()
            conf = qseis.QSeisConfigFull()
            conf.qseis_version = '2006a'
            conf.receiver_distances = [dist / km]
            conf.receiver_azimuths = [azi]
            conf.receiver_depth = config.receiver_depth / km
            conf.source_depth = source.depth / km

            distance_3d_max = math.sqrt(config.distance_max**2 +
                                        (config.source_depth_max -
                                         config.source_depth_min)**2)

            nsamples = trace.nextpow2(
                int(
                    math.ceil(distance_3d_max / vs * 2.0 + 2. * textra) *
                    config.sample_rate))

            conf.time_start = -textra
            conf.time_window = (nsamples - 1) / config.sample_rate
            conf.time_reduction_velocity = 0.0
            conf.nsamples = nsamples
            conf.source_mech = qseis.QSeisSourceMechMT(mnn=source.mnn,
                                                       mee=source.mee,
                                                       mdd=source.mdd,
                                                       mne=source.mne,
                                                       mnd=source.mnd,
                                                       med=source.med)
            conf.earthmodel_1d = mod

            conf.sw_flat_earth_transform = 0
            conf.filter_surface_effects = 1
            conf.wavenumber_sampling = 10.
            conf.wavelet_duration_samples = 0.001
            conf.aliasing_suppression_factor = 0.01

            conf.validate()

            runner.run(conf)

            trs = runner.get_traces()
            for tr in trs:
                pass
                tr.lowpass(4, config.sample_rate / 8., demean=False)
                tr.highpass(4, config.sample_rate / 80.)

            engine = gf.LocalEngine(
                store_dirs=[store_dir_ahfull, store_dir_qseis])

            trs2 = engine.process(source, targets).pyrocko_traces()
            for tr in trs2:
                tr.shift(config.deltat)
                tr.lowpass(4, config.sample_rate / 8., demean=False)
                tr.highpass(4, config.sample_rate / 80.)

            # trace.snuffle(trs+trs2)

            tmin = store.t('{vel:%g}' %
                           (vp / km), source, target) - textra * 0.2
            tmax = store.t('{vel:%g}' %
                           (vs / km), source, target) + textra * 0.2

            for tr in trs + trs2:
                tr.chop(tmin, tmax)

            denom = 0.0
            for cha in 'rtz':
                t1 = g(trs, cha)
                t2 = g(trs2, cha)
                denom += num.sum(t1.ydata**2) + num.sum(t2.ydata**2)

            ds = []
            for cha in 'rtz':
                t1 = g(trs, cha)
                t2 = g(trs2, cha)
                ds.append(2.0 * num.sum((t1.ydata - t2.ydata)**2) / denom)

            ds = num.array(ds)

            # if not num.all(ds < 0.05):
            #    trace.snuffle(trs+trs2)

            assert num.all(ds < 0.05)
Beispiel #2
0
    def test_pyrocko_gf_vs_qseis(self):
        random.seed(2017)

        mod = cake.LayeredModel.from_scanlines(
            cake.read_nd_model_str('''
 0. 5.8 3.46 2.6 1264. 600.
 20. 5.8 3.46 2.6 1264. 600.
 20. 6.5 3.85 2.9 1283. 600.
 35. 6.5 3.85 2.9 1283. 600.
mantle
 35. 8.04 4.48 3.58 1449. 600.
 77.5 8.045 4.49 3.5 1445. 600.
 77.5 8.045 4.49 3.5 180.6 75.
 120. 8.05 4.5 3.427 180. 75.
 120. 8.05 4.5 3.427 182.6 76.06
 165. 8.175 4.509 3.371 188.7 76.55
 210. 8.301 4.518 3.324 201. 79.4
 210. 8.3 4.52 3.321 336.9 133.3
 410. 9.03 4.871 3.504 376.5 146.1
 410. 9.36 5.08 3.929 414.1 162.7
 660. 10.2 5.611 3.918 428.5 172.9
 660. 10.79 5.965 4.229 1349. 549.6'''.lstrip()))

        store_dir = mkdtemp(prefix='gfstore')
        self.tempdirs.append(store_dir)

        qsconf = qseis.QSeisConfig()
        qsconf.qseis_version = '2006a'

        qsconf.time_region = (gf.meta.Timing('0'), gf.meta.Timing('end+100'))

        qsconf.cut = (gf.meta.Timing('0'), gf.meta.Timing('end+100'))

        qsconf.wavelet_duration_samples = 0.001
        qsconf.sw_flat_earth_transform = 0

        config = gf.meta.ConfigTypeA(id='qseis_test',
                                     sample_rate=0.25,
                                     receiver_depth=0. * km,
                                     source_depth_min=10 * km,
                                     source_depth_max=10 * km,
                                     source_depth_delta=1 * km,
                                     distance_min=550 * km,
                                     distance_max=560 * km,
                                     distance_delta=1 * km,
                                     modelling_code_id='qseis.2006a',
                                     earthmodel_1d=mod,
                                     tabulated_phases=[
                                         gf.meta.TPDef(
                                             id='begin',
                                             definition='p,P,p\\,P\\'),
                                         gf.meta.TPDef(id='end',
                                                       definition='2.5'),
                                     ])

        config.validate()
        gf.store.Store.create_editables(store_dir,
                                        config=config,
                                        extra={'qseis': qsconf})

        store = gf.store.Store(store_dir, 'r')
        store.make_ttt()
        store.close()

        try:
            qseis.build(store_dir, nworkers=1)
        except qseis.QSeisError as e:
            if str(e).find('could not start qseis') != -1:
                logger.warn('qseis not installed; '
                            'skipping test_pyrocko_gf_vs_qseis')
                return
            else:
                raise

        source = gf.MTSource(lat=0., lon=0., depth=10. * km)

        source.m6 = tuple(random.random() * 2. - 1. for x in range(6))

        azi = random.random() * 365.
        dist = 553. * km

        dnorth = dist * math.cos(azi * d2r)
        deast = dist * math.sin(azi * d2r)

        targets = []
        for cha in 'rtz':
            target = gf.Target(quantity='displacement',
                               codes=('', '0000', 'PG', cha),
                               north_shift=dnorth,
                               east_shift=deast,
                               depth=config.receiver_depth,
                               store_id='qseis_test')

            dist = source.distance_to(target)
            azi, bazi = source.azibazi_to(target)

            if cha == 'r':
                target.azimuth = bazi + 180.
                target.dip = 0.
            elif cha == 't':
                target.azimuth = bazi - 90.
                target.dip = 0.
            elif cha == 'z':
                target.azimuth = 0.
                target.dip = 90.

            targets.append(target)

        runner = qseis.QSeisRunner()
        conf = qseis.QSeisConfigFull()
        conf.qseis_version = '2006a'
        conf.receiver_distances = [dist / km]
        conf.receiver_azimuths = [azi]
        conf.source_depth = source.depth / km
        conf.time_start = 0.0
        conf.time_window = 508.
        conf.time_reduction_velocity = 0.0
        conf.nsamples = 128
        conf.source_mech = qseis.QSeisSourceMechMT(mnn=source.mnn,
                                                   mee=source.mee,
                                                   mdd=source.mdd,
                                                   mne=source.mne,
                                                   mnd=source.mnd,
                                                   med=source.med)
        conf.earthmodel_1d = mod

        conf.sw_flat_earth_transform = 0

        runner.run(conf)

        trs = runner.get_traces()
        for tr in trs:
            tr.shift(-config.deltat)
            tr.snap(interpolate=True)
            tr.lowpass(4, 0.05)
            tr.highpass(4, 0.01)

        engine = gf.LocalEngine(store_dirs=[store_dir])

        def process_wrap(nthreads=0):
            @benchmark.labeled('pyrocko.gf.process (nthreads-%d)' % nthreads)
            def process(nthreads):
                return engine.process(source, targets, nthreads=nthreads)\
                    .pyrocko_traces()

            return process(nthreads)

        for nthreads in range(1, cpu_count() + 1):
            trs2 = process_wrap(nthreads)
        # print benchmark

        for tr in trs2:
            tr.snap(interpolate=True)
            tr.lowpass(4, 0.05)
            tr.highpass(4, 0.01)

        # trace.snuffle(trs+trs2)

        for cha in 'rtz':
            t1 = g(trs, cha)
            t2 = g(trs2, cha)
            tmin = max(t1.tmin, t2.tmin)
            tmax = min(t1.tmax, t2.tmax)
            t1.chop(tmin, tmax)
            t2.chop(tmin, tmax)
            d = 2.0 * num.sum((t1.ydata - t2.ydata)**2) / \
                (num.sum(t1.ydata**2) + num.sum(t2.ydata**2))

            assert d < 0.05
Beispiel #3
0
                dist = source.distance_to(target)
                azi, bazi = source.azibazi_to(target)

                if cha == 'r':
                    target.azimuth = bazi + 180.
                    target.dip = 0.
                elif cha == 't':
                    target.azimuth = bazi - 90.
                    target.dip = 0.
                elif cha == 'z':
                    target.azimuth = 0.
                    target.dip = 90.

                targets.append(target)

            runner = qseis.QSeisRunner()
            conf = qseis.QSeisConfigFull()
            conf.qseis_version = '2006a'
            conf.receiver_distances = [dist / km]
            conf.receiver_azimuths = [azi]
            conf.receiver_depth = config.receiver_depth / km
            conf.source_depth = source.depth / km

            distance_3d_max = math.sqrt(config.distance_max**2 +
                                        (config.source_depth_max -
                                         config.source_depth_min)**2)

            nsamples = trace.nextpow2(
                int(
                    math.ceil(distance_3d_max / vs * 2.0 + 2. * textra) *
                    config.sample_rate))