Beispiel #1
0
    def test_process_static(self):
        src_length = 5 * km
        src_width = 2 * km
        ntargets = 1600
        interp = ['nearest_neighbor', 'multilinear']
        interpolation = interp[0]

        source = gf.RectangularSource(lat=0.,
                                      lon=0.,
                                      north_shift=0.,
                                      east_shift=0.,
                                      depth=6.5 * km,
                                      width=src_width,
                                      length=src_length,
                                      dip=90.,
                                      rake=90.,
                                      strike=90.,
                                      slip=1.)

        phi = num.zeros(ntargets)  # Horizontal from E
        theta = num.ones(ntargets) * num.pi / 2  # Vertical from vertical
        phi.fill(num.deg2rad(192.))
        theta.fill(num.deg2rad(90. - 23.))

        sattarget = gf.SatelliteTarget(
            north_shifts=(random.rand(ntargets) - .5) * 25. * km,
            east_shifts=(random.rand(ntargets) - .5) * 25. * km,
            tsnapshot=20,
            interpolation=interpolation,
            phi=phi,
            theta=theta)

        static_target = gf.StaticTarget(
            north_shifts=(random.rand(ntargets) - .5) * 25. * km,
            east_shifts=(random.rand(ntargets) - .5) * 25. * km,
            tsnapshot=20,
            interpolation=interpolation)

        engine = gf.LocalEngine(store_dirs=[self.get_pscmp_store_dir()])

        def process_target(nprocs):
            @benchmark.labeled('process-nearest_neighbor-np%d' % nprocs)
            def process_nearest_neighbor():
                sattarget.interpolation = 'nearest_neighbor'
                return engine.process(source, sattarget, nprocs=nprocs)

            @benchmark.labeled('process-multilinear-np%d' % nprocs)
            def process_multilinear():
                sattarget.interpolation = 'multilinear'
                return engine.process(source, sattarget, nprocs=nprocs)

            return process_nearest_neighbor(), process_multilinear()

        def process_multiple_targets():
            return engine.process(source, [sattarget, static_target])

        for np in [1, 2, 4]:
            nn, ml = process_target(nprocs=np)

        process_multiple_targets()
Beispiel #2
0
    def process(self, sources, sandbox, nthreads=0):
        result = {
            "processor_profile": dict(),
            "displacement.n": num.zeros(sandbox.frame.npixel),
            "displacement.e": num.zeros(sandbox.frame.npixel),
            "displacement.d": num.zeros(sandbox.frame.npixel),
        }

        coords = sandbox.frame.coordinatesMeter

        target = gf.StaticTarget(
            lats=num.full(sandbox.frame.npixel, sandbox.frame.llLat),
            lons=num.full(sandbox.frame.npixel, sandbox.frame.llLon),
            east_shifts=coords[:, 0],
            north_shifts=coords[:, 1],
            interpolation="nearest_neighbor",
        )

        store_dirs = set([src.store_dir for src in sources])
        for store_dir in store_dirs:
            self.engine.store_dirs = [store_dir]

            talpa_sources = [
                src for src in sources if src.store_dir == store_dir
            ]

            pyr_sources = [src.pyrocko_source for src in talpa_sources]

            for src in sources:
                src.regularize()

            try:
                res = self.engine.process(pyr_sources, [target],
                                          nthreads=nthreads)

            except Exception as e:
                self._log.error(
                    "Could not execute pyrocko.gf.LocalEngine.process! \n"
                    "LocalEngine Exception: %s" % e)
                continue

            for ires, static_res in enumerate(res.static_results()):
                result["displacement.n"] += static_res.result["displacement.n"]
                result["displacement.e"] += static_res.result["displacement.e"]
                result["displacement.d"] += static_res.result["displacement.d"]

                talpa_sources[ires]._cached_result = static_res.result

        for src in sources:
            if src._cached_result is None:
                continue
            self._log.debug("Using cached displacement for %s" %
                            src.__class__.__name__)
            result["displacement.n"] += src._cached_result["displacement.n"]
            result["displacement.e"] += src._cached_result["displacement.e"]
            result["displacement.d"] += src._cached_result["displacement.d"]

        return result
Beispiel #3
0
    def test_static_timing(self):
        src_length = 5 * km
        src_width = 2 * km
        nstations = 100
        day = 3600 * 24
        interp = ['nearest_neighbor', 'multilinear']
        interpolation = interp[0]

        source = gf.RectangularSource(
            lat=0., lon=0.,
            north_shift=0., east_shift=0., depth=6.5*km,
            width=src_width, length=src_length,
            dip=90., rake=90., strike=90.,
            slip=1.,
            time=time.time()-day)

        source = gf.DCSource(
            lat=0., lon=0.,
            north_shift=0., east_shift=0., depth=6.5*km,
            dip=90., rake=90., strike=90.,
            time=time.time()-day)

        lats = random.uniform(-.2, .2, nstations)
        lons = random.uniform(-.2, .2, nstations)

        target_1 = gf.StaticTarget(
            lats=lats,
            lons=lons,
            interpolation=interpolation,
            tsnapshot=time.time() + day)

        target_2 = gf.StaticTarget(
            lats=lats,
            lons=lons,
            interpolation=interpolation,
            tsnapshot=time.time())

        engine = gf.LocalEngine(store_dirs=[self.get_store_dir('pscmp')])
        res = engine.process(source, [target_1, target_2], nprocs=0)\

        statics_1, statics_2 = res.static_results()
        num.testing.assert_equal(
            statics_1.result['displacement.n'],
            statics_2.result['displacement.n'])
Beispiel #4
0
    def process(self, sources, coords, nthreads=0):
        result = {
            'processor_profile': dict(),
            'displacement.n': num.zeros((coords.shape[0])),
            'displacement.e': num.zeros((coords.shape[0])),
            'displacement.d': num.zeros((coords.shape[0]))
        }

        target = gf.StaticTarget(east_shifts=coords[:, 0],
                                 north_shifts=coords[:, 1],
                                 interpolation='nearest_neighbor')

        store_dirs = set([src.store_dir for src in sources])
        for store_dir in store_dirs:
            self.engine.store_dirs = [store_dir]

            talpa_sources = [
                src for src in sources
                if src.store_dir == store_dir and src._cached_result is None
            ]

            pyr_sources = [src.pyrocko_source for src in talpa_sources]

            for src in pyr_sources:
                src.regularize()

            try:
                res = self.engine.process(pyr_sources, [target],
                                          nthreads=nthreads)

            except Exception as e:
                self._log.error(
                    'Could not execute pyrocko.gf.LocalEngine.process! \n'
                    'LocalEngine Exception: %s' % e)
                continue

            for ires, static_res in enumerate(res.static_results()):
                result['displacement.n'] += static_res.result['displacement.n']
                result['displacement.e'] += static_res.result['displacement.e']
                result['displacement.d'] += static_res.result['displacement.d']

                talpa_sources[ires]._cached_result = static_res.result

        for src in sources:
            if src._cached_result is None:
                continue
            self._log.debug('Using cached displacement for %s' %
                            src.__class__.__name__)
            result['displacement.n'] += src._cached_result['displacement.n']
            result['displacement.e'] += src._cached_result['displacement.e']
            result['displacement.d'] += src._cached_result['displacement.d']

        return result
Beispiel #5
0
    def process(self, sources, coords, nthreads=0):
        result = {
            'processor_profile': dict(),
            'displacement.n': num.zeros((coords.shape[0])),
            'displacement.e': num.zeros((coords.shape[0])),
            'displacement.d': num.zeros((coords.shape[0]))
        }

        target = gf.StaticTarget(
            east_shifts=coords[:, 0],
            north_shifts=coords[:, 1],
            interpolation='nearest_neighbor')

        for store_dir in set([src.store_dir for src in sources]):
            self.engine.store_dirs = [store_dir]

            pyr_sources = [src.pyrocko_source for src in sources
                           if src.store_dir == store_dir]

            for src in pyr_sources:
                src.regularize()

            try:
                res = self.engine.process(
                    pyr_sources, [target],
                    nthreads=nthreads)
            except Exception as e:
                self._log.error(
                    'Could not execute pyrocko.gf.LocalEngine.process! \n'
                    'LocalEngine Exception: %s' % e)
                continue

            for static_res in res.static_results():
                result['displacement.n'] += static_res.result['displacement.n']
                result['displacement.e'] += static_res.result['displacement.e']
                result['displacement.d'] += static_res.result['displacement.d']

        return result
Beispiel #6
0
    def test_sum_static(self):
        from pyrocko.gf import store_ext
        benchmark.show_factor = True

        store = gf.Store(self.get_qseis_store_dir())
        store.open()
        src_length = 2 * km
        src_width = 5 * km
        ntargets = 1600
        interp = ['nearest_neighbor', 'multilinear']
        interpolation = interp[0]

        source = gf.RectangularSource(lat=0.,
                                      lon=0.,
                                      depth=5 * km,
                                      north_shift=0.,
                                      east_shift=0.,
                                      width=src_width,
                                      length=src_length)

        static_target = gf.StaticTarget(
            north_shifts=5 * km + random.rand(ntargets) * 5 * km,
            east_shifts=0 * km + random.rand(ntargets) * 5 * km)
        targets = static_target.get_targets()

        dsource = source.discretize_basesource(store, targets[0])
        source_coords_arr = dsource.coords5()
        mts_arr = dsource.m6s

        receiver_coords_arr = num.empty((len(targets), 5))
        for itarget, target in enumerate(targets):
            receiver = target.receiver(store)
            receiver_coords_arr[itarget, :] = \
                [receiver.lat, receiver.lon, receiver.north_shift,
                 receiver.east_shift, receiver.depth]

        def sum_target(cstore, irecords, delays_t, delays_s, weights, pos,
                       nthreads):
            @benchmark.labeled('sum-timeseries-np%d' % nthreads)
            def sum_timeseries():
                nsummands = weights.size // ntargets
                res = num.zeros(ntargets)
                for t in range(ntargets):
                    sl = slice(t * nsummands, (t + 1) * nsummands)
                    r = store_ext.store_sum(cstore, irecords[sl], delays_t[sl],
                                            weights[sl], pos, 1)
                    res[t] = r[0]
                return res

            @benchmark.labeled('sum-static-np%d' % nthreads)
            def sum_static():
                return store_ext.store_sum_static(cstore, irecords, delays_s,
                                                  weights, pos, ntargets,
                                                  nthreads)

            return sum_timeseries(), sum_static()

        args = (store.cstore, source_coords_arr, mts_arr, receiver_coords_arr,
                'elastic10', interpolation, 0)

        benchmark.clear()
        for nthreads in [1, 2, 4]:
            for (weights, irecords) in store_ext.make_sum_params(*args):
                delays_t = num.zeros_like(weights, dtype=num.float64)
                delays_s = dsource.times.astype(num.float64)
                pos = 6
                t, s = sum_target(store.cstore, irecords, delays_t, delays_s,
                                  weights, pos, nthreads)
                # print benchmark.__str__(header=False)
                num.testing.assert_equal(t, s)
                benchmark.clear()
    def plot_gf_distance_sampling(self):
        origin = gf.Location(lat=10., lon=-15.)

        # test GF store
        TestRF = dict(lat=origin.lat,
                      lon=origin.lon,
                      depth=2. * km,
                      width=1. * km,
                      length=3. * km,
                      rake=uniform(-90., 90.),
                      dip=uniform(0., 90.),
                      strike=uniform(0., 360.),
                      slip=uniform(1., 5.))

        source_plain = gf.RectangularSource(**TestRF)

        N, E = num.meshgrid(num.linspace(-20. * km, 20. * km, nnorth),
                            num.linspace(-20. * km, 20. * km, neast))

        starget_ml = gf.StaticTarget(lats=num.full(N.size, origin.lat),
                                     lons=num.full(N.size, origin.lon),
                                     north_shifts=N.flatten(),
                                     east_shifts=E.flatten(),
                                     interpolation='multilinear')

        # Getting reference gf_distance_sampling = 10.

        def get_displacements(source):
            store_dir, c = self.get_pscmp_store_info()
            engine = gf.LocalEngine(store_dirs=[store_dir])
            r = engine.process(source, starget_ml)
            ref_result = r.static_results()[0]

            compare_results = {}
            for gf_dist_spacing in (
                    0.25,
                    .5,
                    1.,
                    2.,
                    4.,
                    8.,
                    10.,
            ):
                extra_config = psgrn_pscmp.PsGrnPsCmpConfig()
                extra_config.psgrn_config.gf_distance_spacing = gf_dist_spacing
                extra_config.psgrn_config.gf_depth_spacing = .5

                store_dir, c = self._create_psgrn_pscmp_store(extra_config)
                engine = gf.LocalEngine(store_dirs=[store_dir])
                t0 = time()
                r = engine.process(source, starget_ml)
                logger.info('pyrocko stacking time %f s' % (time() - t0))

                static_result = r.static_results()[0]
                compare_results[gf_dist_spacing] = static_result

                num.testing.assert_allclose(
                    ref_result.result['displacement.n'],
                    static_result.result['displacement.n'],
                    atol=1 * mm)
                num.testing.assert_allclose(
                    ref_result.result['displacement.e'],
                    static_result.result['displacement.e'],
                    atol=1 * mm)
                num.testing.assert_allclose(
                    ref_result.result['displacement.d'],
                    static_result.result['displacement.d'],
                    atol=1 * mm)

            return ref_result, compare_results

        # ref_result, compare_results = get_displacements(source_plain)
        # self.plot_displacement_differences(ref_result, compare_results)

        import matplotlib.pyplot as plt

        fig = plt.figure()
        ax = fig.gca()

        for depth in (2., 4., 8., 12.):
            source_plain.depth = depth * km
            ref_result, compare_results = get_displacements(source_plain)
            self.plot_differences(ax,
                                  ref_result,
                                  compare_results,
                                  label='Source Depth %.2f km' % depth)

        ax.legend()

        if show_plot:
            plt.show()
    def fomosto_vs_psgrn_pscmp(self, pscmp_sources, gf_sources, atol=2 * mm):
        def plot_components_compare(fomosto_comps, psgrn_comps):
            import matplotlib.pyplot as plt

            fig, axes = plt.subplots(4, 3)

            for i, (fcomp, pscomp, cname) in enumerate(
                    zip(fomosto_comps, psgrn_comps, ['N', 'E', 'D'])):
                fdispl = fcomp.reshape(nnorth, neast)
                pdispl = pscomp.reshape(nnorth, neast)
                pcbound = num.max([num.abs(pdispl.min()), pdispl.max()])
                # fcbound = num.max([num.abs(fdispl.min()), fdispl.max()])

                axes[0, i].imshow(pdispl,
                                  cmap='seismic',
                                  vmin=-pcbound,
                                  vmax=pcbound)
                axes[1, i].imshow(fdispl,
                                  cmap='seismic',
                                  vmin=-pcbound,
                                  vmax=pcbound)
                diff = pdispl - fdispl
                rdiff = pdispl / fdispl
                axes[2, i].imshow(diff, cmap='seismic')
                axes[3, i].imshow(rdiff, cmap='seismic')

                axes[0, i].set_title('PSCMP %s' % cname)
                axes[1, i].set_title('Fomosto %s' % cname)
                axes[2, i].set_title('abs diff min max %f, %f' %
                                     (diff.min(), diff.max()))
                axes[3, i].set_title('rel diff min max %f, %f' %
                                     (rdiff.min(), rdiff.max()))

            plt.show()

        store_dir, c = self.get_pscmp_store_info()

        origin = gf.Location(lat=10., lon=-15.)

        N, E = num.meshgrid(num.linspace(-20. * km, 20. * km, nnorth),
                            num.linspace(-20. * km, 20. * km, neast))

        # direct pscmp output
        lats, lons = ortd.ne_to_latlon(origin.lat, origin.lon, N.flatten(),
                                       E.flatten())

        cc = c.pscmp_config
        cc.observation = psgrn_pscmp.PsCmpScatter(lats=lats, lons=lons)

        cc.rectangular_source_patches = pscmp_sources
        cc.snapshots = psgrn_pscmp.PsCmpSnapshots(tmin=0.,
                                                  tmax=1.,
                                                  deltatdays=1.)

        ccf = psgrn_pscmp.PsCmpConfigFull(**cc.items())
        ccf.psgrn_outdir = os.path.join(store_dir, c.gf_outdir) + '/'

        t2 = time()
        runner = psgrn_pscmp.PsCmpRunner(keep_tmp=False)
        runner.run(ccf)
        ps2du = runner.get_results(component='displ')[0]
        logger.info('pscmp stacking time %f s' % (time() - t2))

        un_pscmp = ps2du[:, 0]
        ue_pscmp = ps2du[:, 1]
        ud_pscmp = ps2du[:, 2]

        # test against engine
        starget_nn = gf.StaticTarget(lats=num.full(N.size, origin.lat),
                                     lons=num.full(N.size, origin.lon),
                                     north_shifts=N.flatten(),
                                     east_shifts=E.flatten(),
                                     interpolation='nearest_neighbor')

        starget_ml = gf.StaticTarget(lats=num.full(N.size, origin.lat),
                                     lons=num.full(N.size, origin.lon),
                                     north_shifts=N.flatten(),
                                     east_shifts=E.flatten(),
                                     interpolation='multilinear')

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

        for source in gf_sources:
            t0 = time()
            r = engine.process(source, [starget_nn, starget_ml])
            logger.info('pyrocko stacking time %f' % (time() - t0))
            for i, static_result in enumerate(r.static_results()):
                un_fomosto = static_result.result['displacement.n']
                ue_fomosto = static_result.result['displacement.e']
                ud_fomosto = static_result.result['displacement.d']

                if show_plot:
                    fomosto_comps = [un_fomosto, ue_fomosto, ud_fomosto]
                    psgrn_comps = [un_pscmp, ue_pscmp, ud_pscmp]
                    plot_components_compare(fomosto_comps, psgrn_comps)

                num.testing.assert_allclose(un_fomosto, un_pscmp, atol=atol)
                num.testing.assert_allclose(ue_fomosto, ue_pscmp, atol=atol)
                num.testing.assert_allclose(ud_fomosto, ud_pscmp, atol=atol)
Beispiel #9
0
class GFPsgrnPscmpTestCase(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        unittest.TestCase.__init__(self, *args, **kwargs)
        self.tempdirs = []

    def __del__(self):
        import shutil

        for d in self.tempdirs:
            shutil.rmtree(d)

    def test_fomosto_vs_psgrn_pscmp(self):

        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)
        store_id = 'psgrn_pscmp_test'

        version = '2008a'

        c = psgrn_pscmp.PsGrnPsCmpConfig()
        c.psgrn_config.sampling_interval = 1.
        c.psgrn_config.version = version
        c.pscmp_config.version = version

        config = gf.meta.ConfigTypeA(id=store_id,
                                     ncomponents=10,
                                     sample_rate=1. / (3600. * 24.),
                                     receiver_depth=0. * km,
                                     source_depth_min=0. * km,
                                     source_depth_max=5. * km,
                                     source_depth_delta=0.1 * km,
                                     distance_min=0. * km,
                                     distance_max=40. * km,
                                     distance_delta=0.1 * km,
                                     modelling_code_id='psgrn_pscmp.%s' %
                                     version,
                                     earthmodel_1d=mod,
                                     tabulated_phases=[])

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

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

        # build store
        try:
            psgrn_pscmp.build(store_dir, nworkers=1)
        except psgrn_pscmp.PsCmpError, e:
            if str(e).find('could not start psgrn/pscmp') != -1:
                logger.warn('psgrn/pscmp not installed; '
                            'skipping test_pyrocko_gf_vs_pscmp')
                return
            else:
                raise

        origin = gf.Location(lat=10., lon=-15.)

        # test GF store
        TestRF = dict(lat=origin.lat,
                      lon=origin.lon,
                      depth=2. * km,
                      width=2. * km,
                      length=5. * km,
                      rake=90.,
                      dip=45.,
                      strike=45.,
                      slip=1.)

        source = gf.RectangularSource(**TestRF)

        neast = 40
        nnorth = 40

        N, E = num.meshgrid(num.linspace(-20. * km, 20. * km, nnorth),
                            num.linspace(-20. * km, 20. * km, neast))

        starget = gf.StaticTarget(lats=num.array([origin.lat] * N.size),
                                  lons=num.array([origin.lon] * N.size),
                                  north_shifts=N.flatten(),
                                  east_shifts=E.flatten(),
                                  interpolation='nearest_neighbor')
        engine = gf.LocalEngine(store_dirs=[store_dir])
        t0 = time()
        r = engine.process(source, starget)
        t1 = time()
        logger.info('pyrocko stacking time %f' % (t1 - t0))
        un_fomosto = r.static_results()[0].result['displacement.n']
        ue_fomosto = r.static_results()[0].result['displacement.e']
        ud_fomosto = r.static_results()[0].result['displacement.d']

        # test against direct pscmp output
        lats, lons = ortd.ne_to_latlon(origin.lat, origin.lon, N.flatten(),
                                       E.flatten())
        pscmp_sources = [psgrn_pscmp.PsCmpRectangularSource(**TestRF)]

        cc = c.pscmp_config
        cc.observation = psgrn_pscmp.PsCmpScatter(lats=lats, lons=lons)

        cc.rectangular_source_patches = pscmp_sources

        ccf = psgrn_pscmp.PsCmpConfigFull(**cc.items())
        ccf.psgrn_outdir = os.path.join(store_dir, c.gf_outdir) + '/'

        t2 = time()
        runner = psgrn_pscmp.PsCmpRunner(keep_tmp=False)
        runner.run(ccf)
        ps2du = runner.get_results(component='displ')[0]
        t3 = time()
        logger.info('pscmp stacking time %f' % (t3 - t2))

        un_pscmp = ps2du[:, 0]
        ue_pscmp = ps2du[:, 1]
        ud_pscmp = ps2du[:, 2]

        num.testing.assert_allclose(un_fomosto, un_pscmp, atol=0.002)
        num.testing.assert_allclose(ue_fomosto, ue_pscmp, atol=0.002)
        num.testing.assert_allclose(ud_fomosto, ud_pscmp, atol=0.002)
Beispiel #10
0
    def test_fomosto_vs_psgrn_pscmp(self):

        store_dir, c = self.get_pscmp_store_info()

        origin = gf.Location(lat=10., lon=-15.)

        # test GF store
        TestRF = dict(lat=origin.lat,
                      lon=origin.lon,
                      depth=2. * km,
                      width=0.2 * km,
                      length=0.5 * km,
                      rake=90.,
                      dip=45.,
                      strike=45.,
                      slip=num.random.uniform(1., 5.))

        source_plain = gf.RectangularSource(**TestRF)
        source_with_time = gf.RectangularSource(time=123.5, **TestRF)

        neast = 40
        nnorth = 40

        N, E = num.meshgrid(num.linspace(-20. * km, 20. * km, nnorth),
                            num.linspace(-20. * km, 20. * km, neast))

        # direct pscmp output
        lats, lons = ortd.ne_to_latlon(origin.lat, origin.lon, N.flatten(),
                                       E.flatten())
        pscmp_sources = [psgrn_pscmp.PsCmpRectangularSource(**TestRF)]

        cc = c.pscmp_config
        cc.observation = psgrn_pscmp.PsCmpScatter(lats=lats, lons=lons)

        cc.rectangular_source_patches = pscmp_sources

        ccf = psgrn_pscmp.PsCmpConfigFull(**cc.items())
        ccf.psgrn_outdir = os.path.join(store_dir, c.gf_outdir) + '/'

        t2 = time()
        runner = psgrn_pscmp.PsCmpRunner(keep_tmp=False)
        runner.run(ccf)
        ps2du = runner.get_results(component='displ')[0]
        t3 = time()
        logger.info('pscmp stacking time %f' % (t3 - t2))

        un_pscmp = ps2du[:, 0]
        ue_pscmp = ps2du[:, 1]
        ud_pscmp = ps2du[:, 2]

        # test against engine
        starget_nn = gf.StaticTarget(lats=num.full(N.size, origin.lat),
                                     lons=num.full(N.size, origin.lon),
                                     north_shifts=N.flatten(),
                                     east_shifts=E.flatten(),
                                     interpolation='nearest_neighbor')

        starget_ml = gf.StaticTarget(lats=num.full(N.size, origin.lat),
                                     lons=num.full(N.size, origin.lon),
                                     north_shifts=N.flatten(),
                                     east_shifts=E.flatten(),
                                     interpolation='multilinear')

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

        for source in [source_plain, source_with_time]:
            t0 = time()
            r = engine.process(source, [starget_nn, starget_ml])
            t1 = time()
            logger.info('pyrocko stacking time %f' % (t1 - t0))
            for static_result in r.static_results():
                un_fomosto = static_result.result['displacement.n']
                ue_fomosto = static_result.result['displacement.e']
                ud_fomosto = static_result.result['displacement.d']

                num.testing.assert_allclose(un_fomosto, un_pscmp, atol=1 * mm)
                num.testing.assert_allclose(ue_fomosto, ue_pscmp, atol=1 * mm)
                num.testing.assert_allclose(ud_fomosto, ud_pscmp, atol=1 * mm)