コード例 #1
0
def test_cube_slice_w_ignore_dead_traces_trilinear():
    """Get cube slice trilinear aka Auto4D input, with scrambled data with
    dead traces to be ignored, various YFLIP cases."""

    cube1 = Cube(XCUB2)

    surf1 = RegularSurface()
    surf1.from_cube(cube1, 1000.0)

    cells = [(18, 12), (20, 2), (0, 4)]

    surf1.slice_cube(cube1,
                     sampling="trilinear",
                     snapxy=True,
                     deadtraces=False)
    plotfile = ojn(td, "slice_tri1.png")
    title = "Cube with dead traces; trilinear; keep as is at dead traces"
    surf1.quickplot(filename=plotfile, minmax=(-10000, 10000), title=title)

    for cell in cells:
        icell, jcell = cell
        assert surf1.values[icell,
                            jcell] == pytest.approx(cube1.values[icell, jcell,
                                                                 0],
                                                    abs=0.1)
    assert ma.count_masked(surf1.values) == 0  # shall be no masked cells
コード例 #2
0
def test_avg02():
    """Make average map from Reek Eclipse."""
    grd = Grid()
    grd.from_file(GFILE2, fformat="egrid")

    # get the poro
    po = GridProperty()
    po.from_file(IFILE2, fformat="init", name="PORO", grid=grd)

    # get the dz and the coordinates
    dz = grd.get_dz(mask=False)
    xc, yc, _zc = grd.get_xyz(mask=False)

    # get actnum
    actnum = grd.get_actnum()

    # convert from masked numpy to ordinary
    xcuse = np.copy(xc.values3d)
    ycuse = np.copy(yc.values3d)
    dzuse = np.copy(dz.values3d)
    pouse = np.copy(po.values3d)

    # dz must be zero for undef cells
    dzuse[actnum.values3d < 0.5] = 0.0
    pouse[actnum.values3d < 0.5] = 0.0

    # make a map... estimate from xc and yc
    zuse = np.ones((xcuse.shape))

    avgmap = RegularSurface(
        nx=200,
        ny=250,
        xinc=50,
        yinc=50,
        xori=457000,
        yori=5927000,
        values=np.zeros((200, 250)),
    )

    avgmap.avg_from_3dprop(
        xprop=xcuse,
        yprop=ycuse,
        zoneprop=zuse,
        zone_minmax=(1, 1),
        mprop=pouse,
        dzprop=dzuse,
        truncate_le=None,
    )

    # add the faults in plot
    fau = Polygons(FFILE1, fformat="zmap")
    fspec = {"faults": fau}

    avgmap.quickplot(filename="TMP/tmp_poro2.png",
                     xlabelrotation=30,
                     faults=fspec)
    avgmap.to_file("TMP/tmp.poro.gri", fformat="irap_ascii")

    logger.info(avgmap.values.mean())
    assert avgmap.values.mean() == pytest.approx(0.1653, abs=0.01)
コード例 #3
0
def test_slice_nearest(load_cube_rsgy1):
    """Slice a cube with a surface, nearest node."""

    t1 = xtg.timer()
    logger.info('Loading surface')
    xs = RegularSurface(rtop1)

    xs.to_file(td + '/surf_slice_cube_initial.gri')

    logger.info('Loading cube')
    kube = load_cube_rsgy1

    # now slice
    logger.info('Slicing cube which has YFLIP status {}'.format(kube.yflip))

    t1 = xtg.timer()
    print(t1)
    xs.slice_cube(kube)
    t2 = xtg.timer(t1)
    logger.info('Slicing...done in {} seconds'.format(t2))

    xs.to_file(td + '/surf_slice_cube.fgr', fformat='irap_ascii')
    xs.to_file(td + '/surf_slice_cube.gri', fformat='irap_binary')

    xs.quickplot(filename=td + '/surf_slice_cube.png',
                 colortable='seismic',
                 minmax=(-1, 1),
                 title='Reek',
                 infotext='Method: nearest')

    mean = xs.values.mean()

    logger.info(xs.values.min())
    logger.info(xs.values.max())

    mean = xs.values.mean()
    assert mean == pytest.approx(0.0198142, abs=0.001)  # 0.019219 in RMS
    logger.info('Avg X is {}'.format(mean))

    # try same ting with swapaxes active ==================================
    ys = RegularSurface()
    ys.from_file(rtop1)

    kube.swapaxes()
    # Now slice
    logger.info('Slicing... (now with swapaxes)')
    ys.slice_cube(kube)
    logger.info('Slicing...done')
    mean = ys.values.mean()
    logger.info('Avg for surface is now {}'.format(mean))

    ys.to_file(td + '/surf_slice_cube_swap.gri')
    assert mean == pytest.approx(0.0198142, abs=0.003)
コード例 #4
0
def test_cube_slice_w_ignore_dead_traces_nearest():
    """Get cube slice nearest aka Auto4D input, with scrambled data with
    dead traces, various YFLIP cases, ignore dead traces."""

    cube1 = Cube(XCUB2)

    surf1 = RegularSurface()
    surf1.from_cube(cube1, 1000.1)

    cells = ((18, 12), (20, 2), (0, 4))

    surf1.slice_cube(cube1, deadtraces=False)
    plotfile = ojn(td, "slice_nea1.png")
    title = "Cube with dead traces; nearest; use just values as is"
    surf1.quickplot(filename=plotfile, minmax=(-10000, 10000), title=title)

    for cell in cells:
        icell, jcell = cell
        assert surf1.values[icell,
                            jcell] == pytest.approx(cube1.values[icell, jcell,
                                                                 0],
                                                    abs=0.01)
    assert ma.count_masked(surf1.values) == 0  # shall be no masked cells

    # swap surface
    surf2 = surf1.copy()
    surf2.values = 1000.1

    surf2.swapaxes()

    surf2.slice_cube(cube1, deadtraces=False)

    assert surf2.values.mean() == pytest.approx(surf1.values.mean(), rel=0.001)

    # swap surface and cube
    surf2 = surf1.copy()
    surf2.values = 1000.1
    surf2.swapaxes()

    cube2 = cube1.copy()
    cube2.swapaxes()
    surf2.slice_cube(cube2, deadtraces=False)
    assert surf2.values.mean() == pytest.approx(surf1.values.mean(), rel=0.001)

    # swap cube only
    surf2 = surf1.copy()
    surf2.values = 1000.1

    cube2 = cube1.copy()
    cube2.swapaxes()
    surf2.slice_cube(cube2, deadtraces=False)
    assert surf2.values.mean() == pytest.approx(surf1.values.mean(), rel=0.001)
コード例 #5
0
def test_avg03():
    """Make average map from Reek Eclipse, speed up by zone_avg."""
    g = Grid()
    g.from_file(gfile2, fformat="egrid")

    # get the poro
    po = GridProperty()
    po.from_file(ifile2, fformat='init', name='PORO', grid=g)

    # get the dz and the coordinates
    dz = g.get_dz(mask=False)
    xc, yc, zc = g.get_xyz(mask=False)

    # get actnum
    actnum = g.get_actnum()
    actnum = actnum.get_npvalues3d()

    # convert from masked numpy to ordinary
    xcuse = xc.get_npvalues3d()
    ycuse = yc.get_npvalues3d()
    dzuse = dz.get_npvalues3d(fill_value=0.0)
    pouse = po.get_npvalues3d(fill_value=0.0)

    # dz must be zero for undef cells
    dzuse[actnum < 0.5] = 0.0
    pouse[actnum < 0.5] = 0.0

    # make a map... estimate from xc and yc
    zuse = np.ones((xcuse.shape))

    avgmap = RegularSurface(nx=200, ny=250, xinc=50, yinc=50,
                            xori=457000, yori=5927000,
                            values=np.zeros((200, 250)))

    avgmap.avg_from_3dprop(xprop=xcuse, yprop=ycuse, zoneprop=zuse,
                           zone_minmax=(1, 1),
                           mprop=pouse, dzprop=dzuse,
                           truncate_le=None, zone_avg=True)

    # add the faults in plot
    fau = Polygons(ffile1, fformat='zmap')
    fspec = {'faults': fau}

    avgmap.quickplot(filename='TMP/tmp_poro3.png', xlabelrotation=30,
                     faults=fspec)
    avgmap.to_file('TMP/tmp.poro3.gri', fformat='irap_ascii')

    logger.info(avgmap.values.mean())
    assert avgmap.values.mean() == pytest.approx(0.1653, abs=0.01)
コード例 #6
0
def test_slice_attr_window_max_w_plotting(load_cube_rsgy1):
    """Slice a cube within a window, get max/min etc, using trilinear
    interpol and plotting."""

    logger.info("Loading surface")
    xs1 = RegularSurface(RTOP1)
    xs2 = xs1.copy()
    xs3 = xs1.copy()

    logger.info("Loading cube")
    kube = load_cube_rsgy1

    t1 = xtg.timer()
    xs1.slice_cube_window(kube, attribute="min", sampling="trilinear")
    t2 = xtg.timer(t1)
    logger.info("Window slicing... {} secs".format(t2))

    xs1.quickplot(
        filename=td + "/surf_slice_cube_window_min.png",
        colortable="seismic",
        minmax=(-1, 1),
        title="Reek Minimum",
        infotext="Method: trilinear, window",
    )

    xs2.slice_cube_window(kube,
                          attribute="max",
                          sampling="trilinear",
                          showprogress=True)

    xs2.quickplot(
        filename=td + "/surf_slice_cube_window_max.png",
        colortable="seismic",
        minmax=(-1, 1),
        title="Reek Maximum",
        infotext="Method: trilinear, window",
    )

    xs3.slice_cube_window(kube, attribute="rms", sampling="trilinear")

    xs3.quickplot(
        filename=td + "/surf_slice_cube_window_rms.png",
        colortable="jet",
        minmax=(0, 1),
        title="Reek rms (root mean square)",
        infotext="Method: trilinear, window",
    )
コード例 #7
0
def test_slice_various_reek(tmpdir, load_cube_rsgy1):
    """Slice a cube with a surface, both nearest node and interpol, Reek."""

    logger.info("Loading surface")
    xs = RegularSurface(RTOP1)

    logger.info("Loading cube")
    kube = load_cube_rsgy1

    t1 = xtg.timer()
    xs.slice_cube(kube)
    t2 = xtg.timer(t1)
    logger.info("Slicing... nearest, done in {} seconds".format(t2))

    xs.to_file(join(tmpdir, "surf_slice_cube_reek_interp.gri"))

    xs.quickplot(
        filename=join(tmpdir, "surf_slice_cube_reek_interp.png"),
        colortable="seismic",
        minmax=(-1, 1),
        title="Reek",
        infotext="Method: nearest",
    )

    # trilinear interpolation:

    logger.info("Loading surface")
    xs = RegularSurface(RTOP1)

    t1 = xtg.timer()
    xs.slice_cube(kube, sampling="trilinear")
    t2 = xtg.timer(t1)
    logger.info("Slicing... trilinear, done in {} seconds".format(t2))

    xs.to_file(join(tmpdir, "surf_slice_cube_reek_trilinear.gri"))

    xs.quickplot(
        filename=join(tmpdir, "surf_slice_cube_reek_trilinear.png"),
        colortable="seismic",
        minmax=(-1, 1),
        title="Reek",
        infotext="Method: trilinear",
    )
コード例 #8
0
def test_slice_attr_window_max_w_plotting(load_cube_rsgy1):
    """Slice a cube within a window, get max/min etc, using trilinear
    interpol and plotting."""

    logger.info('Loading surface')
    xs1 = RegularSurface(rtop1)
    xs2 = xs1.copy()
    xs3 = xs1.copy()

    logger.info('Loading cube')
    kube = load_cube_rsgy1

    t1 = xtg.timer()
    xs1.slice_cube_window(kube, attribute='min', sampling='trilinear')
    t2 = xtg.timer(t1)
    logger.info('Window slicing... {} secs'.format(t2))

    xs1.quickplot(filename=td + '/surf_slice_cube_window_min.png',
                  colortable='seismic',
                  minmax=(-1, 1),
                  title='Reek Minimum',
                  infotext='Method: trilinear, window')

    xs2.slice_cube_window(kube,
                          attribute='max',
                          sampling='trilinear',
                          showprogress=True)

    xs2.quickplot(filename=td + '/surf_slice_cube_window_max.png',
                  colortable='seismic',
                  minmax=(-1, 1),
                  title='Reek Maximum',
                  infotext='Method: trilinear, window')

    xs3.slice_cube_window(kube, attribute='rms', sampling='trilinear')

    xs3.quickplot(filename=td + '/surf_slice_cube_window_rms.png',
                  colortable='jet',
                  minmax=(0, 1),
                  title='Reek rms (root mean square)',
                  infotext='Method: trilinear, window')
コード例 #9
0
def test_slice_nearest_v2(tmpdir, load_cube_rsgy1):
    """Slice a cube with a surface, nearest node, algorithm 2."""

    xs = RegularSurface(RTOP1)

    kube = load_cube_rsgy1

    t1 = xtg.timer()

    xs.slice_cube(kube, algorithm=2)
    logger.info("Slicing...done in {} seconds".format(xtg.timer(t1)))

    xs.to_file(join(tmpdir, "surf_slice_cube_alg2.gri"), fformat="irap_binary")

    xs.quickplot(
        filename=join(tmpdir, "surf_slice_cube_alg2.png"),
        colortable="seismic",
        minmax=(-1, 1),
        title="Reek",
        infotext="Method: nearest",
    )
コード例 #10
0
def test_slice_nearest(load_cube_rsgy1):
    """Slice a cube with a surface, nearest node, algorithm 1"""

    xs = RegularSurface(RTOP1)
    xs.to_file(td + "/surf_slice_cube_initial.gri")

    kube = load_cube_rsgy1

    t1 = xtg.timer()
    xs.slice_cube(kube, algorithm=1)
    logger.info("Slicing...done in {} seconds".format(xtg.timer(t1)))

    xs.to_file(td + "/surf_slice_cube_v1.gri", fformat="irap_binary")

    xs.quickplot(
        filename=td + "/surf_slice_cube_near_v1.png",
        colortable="seismic",
        minmax=(-1, 1),
        title="Reek",
        infotext="Method: nearest, algorithm 1",
    )
コード例 #11
0
def test_cube_slice_auto4d_data():
    """Get cube slice aka Auto4D input, with synthetic/scrambled data"""

    xs1 = RegularSurface(XTOP1, fformat="gri")
    xs1.describe()

    xs1out = ojn(td, "XTOP1.ijxyz")
    xs1.to_file(xs1out, fformat="ijxyz")

    xs2 = RegularSurface(xs1out, fformat="ijxyz")

    assert xs1.values.mean() == pytest.approx(xs2.values.mean(), abs=0.0001)

    kube1 = Cube(XCUB1)
    kube1.describe()

    assert xs2.nactive == 10830

    xs2.slice_cube_window(kube1,
                          sampling="trilinear",
                          mask=True,
                          attribute="max")

    xs2out1 = ojn(td, "XTOP2_sampled_from_cube.ijxyz")
    xs2out2 = ojn(td, "XTOP2_sampled_from_cube.gri")
    xs2out3 = ojn(td, "XTOP2_sampled_from_cube.png")

    xs2.to_file(xs2out1, fformat="ijxyz")
    xs2.to_file(xs2out2)

    assert xs2.nactive == 3275  # 3320  # shall be fewer cells

    xs2.quickplot(
        filename=xs2out3,
        colortable="seismic",
        title="Auto4D Test",
        minmax=(0, 12000),
        infotext="Method: max",
    )
コード例 #12
0
def test_resample_partial_sample(tmp_path, reek_map, generate_plot):
    """Do resampling from one surface to another with partial sampling."""
    sml = reek_map

    # note: values is missing by purpose:
    snew = RegularSurface(
        ncol=round(sml.ncol * 0.6),
        nrow=round(sml.nrow * 0.6),
        xori=sml.xori - 2000,
        yori=sml.yori + 3000,
        xinc=sml.xinc * 0.6,
        yinc=sml.xinc * 0.6,
        rotation=sml.rotation,
        yflip=sml.yflip,
    )

    print(sml.yflip)

    logger.info(snew.values)

    snew.resample(sml, mask=True)

    assert snew.values.mean() == pytest.approx(1726.65)

    if generate_plot:
        sml.quickplot(tmp_path / "resampled_input.png")
        snew.quickplot(tmp_path / "resampled_output.png")
        sml.to_file(tmp_path / "resampled_input.gri")
        snew.to_file(tmp_path / "resampled_output.gri")

    snew2 = snew.copy()
    snew2._yflip = -1
    snew2._xori -= 4000
    snew2._yori -= 2000
    snew2.resample(sml, mask=True)

    if generate_plot:
        snew2.to_file(tmp_path / "resampled_output2.gri")
    assert snew2.values.mean() == pytest.approx(1747.20, abs=0.2)
コード例 #13
0
def test_cube_slice_w_dead_traces_nearest(tmpdir):
    """Get cube slice nearest aka Auto4D input, with scrambled data with
    dead traces, various YFLIP cases, undef at dead traces."""

    cube1 = Cube(XCUB2)

    surf1 = RegularSurface()
    surf1.from_cube(cube1, 1000.1)

    cells = ((18, 12),)

    surf1.slice_cube(cube1, deadtraces=True, algorithm=1)
    plotfile = join(tmpdir, "slice_nea1_dead1.png")
    title = "Cube with dead traces; nearest; UNDEF at dead traces"
    surf1.quickplot(filename=plotfile, minmax=(-10000, 10000), title=title)

    for cell in cells:
        icell, jcell = cell
        assert surf1.values[icell, jcell] == cube1.values[icell, jcell, 0]

    ndead = (cube1.traceidcodes == 2).sum()

    assert ma.count_masked(surf1.values) == ndead

    surf2 = RegularSurface()
    surf2.from_cube(cube1, 1000.1)

    surf2.slice_cube(cube1, deadtraces=True, algorithm=2)
    plotfile = join(tmpdir, "slice_nea1_dead2.png")
    title = "Cube with dead traces; nearest; UNDEF at dead traces algo 2"
    surf1.quickplot(filename=plotfile, minmax=(-10000, 10000), title=title)

    for cell in cells:
        icell, jcell = cell
        assert surf2.values[icell, jcell] == cube1.values[icell, jcell, 0]

    ndead = (cube1.traceidcodes == 2).sum()

    assert ma.count_masked(surf1.values) == ndead
コード例 #14
0
def test_slice_various_reek(load_cube_rsgy1):
    """Slice a cube with a surface, both nearest node and interpol, Reek."""

    logger.info('Loading surface')
    xs = RegularSurface(rtop1)

    logger.info('Loading cube')
    kube = load_cube_rsgy1

    t1 = xtg.timer()
    xs.slice_cube(kube)
    t2 = xtg.timer(t1)
    logger.info('Slicing... nearest, done in {} seconds'.format(t2))

    xs.to_file(td + '/surf_slice_cube_reek_interp.gri')

    xs.quickplot(filename=td + '/surf_slice_cube_reek_interp.png',
                 colortable='seismic',
                 minmax=(-1, 1),
                 title='Reek',
                 infotext='Method: nearest')

    # trilinear interpolation:

    logger.info('Loading surface')
    xs = RegularSurface(rtop1)

    t1 = xtg.timer()
    xs.slice_cube(kube, sampling='trilinear')
    t2 = xtg.timer(t1)
    logger.info('Slicing... trilinear, done in {} seconds'.format(t2))

    xs.to_file(td + '/surf_slice_cube_reek_trilinear.gri')

    xs.quickplot(filename=td + '/surf_slice_cube_reek_trilinear.png',
                 colortable='seismic',
                 minmax=(-1, 1),
                 title='Reek',
                 infotext='Method: trilinear')
コード例 #15
0
def test_cube_slice_auto4d_data():
    """Get cube slice aka Auto4D input, with synthetic/scrambled data"""

    xs1 = RegularSurface(xtop1, fformat='gri')
    xs1.describe()

    xs1out = ojn(td, 'xtop1.ijxyz')
    xs1.to_file(xs1out, fformat='ijxyz')

    xs2 = RegularSurface(xs1out, fformat='ijxyz')

    assert xs1.values.mean() == pytest.approx(xs2.values.mean(), abs=0.0001)

    kube1 = Cube(xcub1)
    kube1.describe()

    assert xs2.nactive == 10830

    xs2.slice_cube_window(kube1,
                          sampling='trilinear',
                          mask=True,
                          attribute='max')

    xs2out1 = ojn(td, 'xtop2_sampled_from_cube.ijxyz')
    xs2out2 = ojn(td, 'xtop2_sampled_from_cube.gri')
    xs2out3 = ojn(td, 'xtop2_sampled_from_cube.png')

    xs2.to_file(xs2out1, fformat='ijxyz')
    xs2.to_file(xs2out2)

    assert xs2.nactive == 3320  # shall be fewer cells

    xs2.quickplot(filename=xs2out3,
                  colortable='seismic',
                  title='Auto4D Test',
                  minmax=(0, 12000),
                  infotext='Method: max')
コード例 #16
0
def test_cube_slice_w_dead_traces_nearest():
    """Get cube slice nearest aka Auto4D input, with scrambled data with
    dead traces, various YFLIP cases, undef at dead traces."""

    cube1 = Cube(xcub2)

    surf1 = RegularSurface()
    surf1.from_cube(cube1, 1000.1)

    cells = ((18, 12), )

    surf1.slice_cube(cube1, deadtraces=True)
    plotfile = ojn(td, 'slice_nea1_dead.png')
    title = 'Cube with dead traces; nearest; UNDEF at dead traces'
    surf1.quickplot(filename=plotfile, minmax=(-10000, 10000), title=title)

    for cell in cells:
        icell, jcell = cell
        assert surf1.values[icell, jcell] == cube1.values[icell, jcell, 0]

    ndead = (cube1.traceidcodes == 2).sum()
    print(ndead)

    assert ma.count_masked(surf1.values) == ndead

    # swap cube only
    surf2 = surf1.copy()
    surf2.values = 1000.1

    cube2 = cube1.copy()
    cube2.swapaxes()
    surf2.slice_cube(cube2, deadtraces=True)
    plotfile = ojn(td, 'slice_nea1_dead_cubeswap.png')
    surf2.quickplot(filename=plotfile, minmax=(-10000, 10000))
    assert ma.count_masked(surf2.values) == ndead
    assert surf2.values.mean() == surf1.values.mean()
コード例 #17
0
def test_hcpvfz1():
    """HCPV thickness map."""

    # It is important that input are pure numpies, not masked

    logger.info("Name is %s", __name__)
    grd = Grid()
    logger.info("Import roff...")
    grd.from_file(ROFF1_GRID, fformat="roff")

    # get the hcpv
    st = GridProperty()
    to = GridProperty()

    st.from_file(ROFF1_PROPS, name="Oil_HCPV")

    to.from_file(ROFF1_PROPS, name="Oil_bulk")

    # get the dz and the coordinates, with no mask (ie get value for outside)
    dz = grd.get_dz(mask=False)
    xc, yc, _zc = grd.get_xyz(mask=False)

    xcv = ma.filled(xc.values3d)
    ycv = ma.filled(yc.values3d)
    dzv = ma.filled(dz.values3d)

    hcpfz = ma.filled(st.values3d, fill_value=0.0)
    tov = ma.filled(to.values3d, fill_value=10)
    tov[tov < 1.0e-32] = 1.0e-32
    hcpfz = hcpfz * dzv / tov

    # make a map... estimate from xc and yc
    xmin = xcv.min()
    xmax = xcv.max()
    ymin = ycv.min()
    ymax = ycv.max()
    xinc = (xmax - xmin) / 50
    yinc = (ymax - ymin) / 50

    logger.debug(
        "xmin xmax ymin ymax, xinc, yinc: %s %s %s %s %s %s",
        xmin,
        xmax,
        ymin,
        ymax,
        xinc,
        yinc,
    )

    hcmap = RegularSurface(
        nx=50,
        ny=50,
        xinc=xinc,
        yinc=yinc,
        xori=xmin,
        yori=ymin,
        values=np.zeros((50, 50)),
    )

    hcmap2 = RegularSurface(
        nx=50,
        ny=50,
        xinc=xinc,
        yinc=yinc,
        xori=xmin,
        yori=ymin,
        values=np.zeros((50, 50)),
    )

    zp = np.ones((grd.ncol, grd.nrow, grd.nlay))
    # now make hcpf map

    t1 = xtg.timer()
    hcmap.hc_thickness_from_3dprops(
        xprop=xcv,
        yprop=ycv,
        dzprop=dzv,
        hcpfzprop=hcpfz,
        zoneprop=zp,
        zone_minmax=(1, 1),
    )

    assert hcmap.values.mean() == pytest.approx(1.447, abs=0.1)

    t2 = xtg.timer(t1)

    logger.info("Speed basic is %s", t2)

    t1 = xtg.timer()
    hcmap2.hc_thickness_from_3dprops(
        xprop=xcv,
        yprop=ycv,
        dzprop=dzv,
        hcpfzprop=hcpfz,
        zoneprop=zp,
        coarsen=2,
        zone_avg=True,
        zone_minmax=(1, 1),
        mask_outside=True,
    )
    t2 = xtg.timer(t1)

    logger.info("Speed zoneavg coarsen 2 is %s", t2)

    hcmap.quickplot(filename="TMP/quickplot_hcpv.png")
    hcmap2.quickplot(filename="TMP/quickplot_hcpv_zavg_coarsen.png")
    logger.debug(hcmap.values.mean())