def test_cube_resampling(loadsfile1): """Import a cube, then make a smaller and resample, then export the new""" logger.info("Import SEGY format via SEGYIO") incube = loadsfile1 newcube = Cube( xori=460500, yori=5926100, zori=1540, xinc=40, yinc=40, zinc=5, ncol=200, nrow=100, nlay=100, rotation=incube.rotation, yflip=incube.yflip, ) newcube.resample(incube, sampling="trilinear", outside_value=10.0) assert newcube.values.mean() == pytest.approx(5.3107, 0.0001) assert newcube.values[20, 20, 20] == pytest.approx(10.0, 0.0001)
def test_cube_slice_w_dead_traces_trilinear(tmpdir): """Get cube slice trilinear aka Auto4D input, with scrambled data with dead traces to be ignored, various YFLIP cases.""" cube1 = Cube(XCUB2) surf1 = xtgeo.surface_from_cube(cube1, 1000.0) cells = [(18, 12)] surf1.slice_cube(cube1, sampling="trilinear", snapxy=True, deadtraces=True) plotfile = join(tmpdir, "slice_tri1_dead.png") title = "Cube with dead traces; trilinear; UNDEF at dead traces" surf1.quickplot(filename=plotfile, minmax=(-10000, 10000), title=title) ndead = (cube1.traceidcodes == 2).sum() for cell in cells: icell, jcell = cell assert surf1.values[icell, jcell] == pytest.approx( cube1.values[icell, jcell, 0], 0.1 ) assert ma.count_masked(surf1.values) == ndead # swap cubes and map surf2 = surf1.copy() surf2.values = 1000.0 cube2 = cube1.copy() cube2.swapaxes() surf2.swapaxes() surf2.slice_cube(cube2, sampling="trilinear", deadtraces=True) plotfile = join(tmpdir, "slice_tri1__dead_cubeswap.png") surf2.quickplot(filename=plotfile, minmax=(-10000, 10000)) assert ma.count_masked(surf2.values) == ndead tsetup.assert_almostequal(surf2.values.mean(), surf1.values.mean(), 0.01)
def test_cube_slice_w_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 = xtgeo.surface_from_cube(cube1, 1000.0) cells = [(18, 12)] surf1.slice_cube(cube1, sampling='trilinear', snapxy=True, deadtraces=True) plotfile = ojn(td, 'slice_tri1_dead.png') title = 'Cube with dead traces; trilinear; UNDEF at dead traces' surf1.quickplot(filename=plotfile, minmax=(-10000, 10000), title=title) ndead = (cube1.traceidcodes == 2).sum() for cell in cells: icell, jcell = cell assert surf1.values[icell, jcell] == \ pytest.approx(cube1.values[icell, jcell, 0], 0.1) assert ma.count_masked(surf1.values) == ndead # swap cube only surf2 = surf1.copy() surf2.values = 1000.0 cube2 = cube1.copy() cube2.swapaxes() surf2.slice_cube(cube2, sampling='trilinear', deadtraces=True) plotfile = ojn(td, 'slice_tri1__dead_cubeswap.png') surf2.quickplot(filename=plotfile, minmax=(-10000, 10000)) assert ma.count_masked(surf2.values) == ndead assert surf2.values.mean() == surf1.values.mean()
def test_cube_randomline(show_plot): """Import a cube, and compute a randomline given a simple Polygon""" incube = Cube(SFILE4) poly = xtgeo.Polygons() poly.from_list([[778133, 6737650, 2000, 1], [776880, 6738820, 2000, 1]]) logger.info("Generate random line...") hmin, hmax, vmin, vmax, random = incube.get_randomline(poly) assert hmin == pytest.approx(-15.7, 0.1) assert random.mean() == pytest.approx(-12.5, 0.1) if show_plot: import matplotlib.pyplot as plt plt.figure() plt.imshow( random, cmap="seismic", interpolation="sinc", extent=(hmin, hmax, vmax, vmin), ) plt.axis("tight") plt.colorbar() plt.show()
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)
def test_segy_scantraces(): """Scan and report SEGY first and last trace (internal reader).""" print("HELLO") logger.info("Scan traces...") Cube().scan_segy_traces(SFILE1, outfile="TMP/cube_scantraces")
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
def test_segyio_import_export(tmpdir, loadsfile1): """Import and export SEGY (case 1 Reek) via SegIO library.""" logger.info("Import SEGY format via SEGYIO") xcu = loadsfile1 assert xcu.ncol == 408, "NCOL" dim = xcu.values.shape logger.info("Dimension is %s", dim) assert dim == (408, 280, 70), "Dimensions 3D" assert xcu.values.max() == pytest.approx(7.42017, 0.001) input_mean = xcu.values.mean() logger.info(input_mean) xcu.values += 200 xcu.to_file(join(tmpdir, "reek_cube.segy")) # reread that file y = Cube(join(tmpdir, "reek_cube.segy")) logger.info(y.values.mean())
def test_swapaxis_ncol_nrow(): cube = Cube( xori=0.0, yori=0.0, zori=0.0, ncol=2, nrow=3, nlay=2, xinc=1.0, yinc=1.0, zinc=1.0, yflip=1, ) cube.swapaxes() assert (cube.nrow, cube.ncol) == (2, 3)
def test_segy_scanheader(): """Scan SEGY and report header, using XTGeo internal reader.""" logger.info("Scan header...") if not os.path.isfile(SFILE1): raise Exception("No such file") Cube().scan_segy_header(SFILE1, outfile=join(TMD, "cube_scanheader"))
def test_swapaxis_xinc_yinc(): cube = Cube( xori=0.0, yori=0.0, zori=0.0, ncol=2, nrow=3, nlay=2, xinc=1.0, yinc=2.0, zinc=1.0, yflip=1, ) cube.swapaxes() assert (cube.xinc, cube.yinc) == (2, 1)
def test_create(): """Create default cube instance.""" xcu = Cube() assert xcu.ncol == 5, "NCOL" assert xcu.nrow == 3, "NROW" vec = xcu.values xdim, _ydim, _zdim = vec.shape assert xdim == 5, "NX from numpy shape "
def test_cube_randomline(): """Import a cube, and compute a randomline given a simple Polygon""" # import matplotlib.pyplot as plt incube = Cube(SFILE4) # make a polyline with two points dfr = pd.DataFrame( np.array([[778133, 6737650, 2000, 1], [776880, 6738820, 2000, 1]]), columns=["X_UTME", "Y_UTMN", "Z_TVDSS", "POLY_ID"], ) poly = xtgeo.Polygons() poly.dataframe = dfr logger.info("Generate random line...") hmin, hmax, vmin, vmax, random = incube.get_randomline(poly)
def test_swapaxis_ilines(): cube = Cube( xori=0.0, yori=0.0, zori=0.0, ncol=2, nrow=2, nlay=2, xinc=1.0, yinc=1.0, zinc=1.0, yflip=1, values=[1, 2, 3, 4, 5, 6, 7, 8], ) assert cube.ilines.tolist() == [1, 2] cube.swapaxes() assert cube.ilines.tolist() == [1, 2]
def test_swapaxis_rotation(rotation, expected_rotation): cube = Cube( xori=0.0, yori=0.0, zori=0.0, ncol=2, nrow=2, nlay=2, xinc=1.0, yinc=1.0, zinc=1.0, yflip=1, rotation=rotation, values=[1, 2, 3, 4, 5, 6, 7, 8], ) cube.swapaxes() assert cube.rotation == expected_rotation
def test_swapaxis(): cube = Cube( xori=0.0, yori=0.0, zori=0.0, ncol=2, nrow=2, nlay=2, xinc=1.0, yinc=1.0, zinc=1.0, yflip=1, values=[1, 2, 3, 4, 5, 6, 7, 8], ) assert cube.values.flatten().tolist() == [1, 2, 3, 4, 5, 6, 7, 8] cube.swapaxes() assert cube.values.flatten().tolist() == [1.0, 2.0, 5.0, 6.0, 3.0, 4.0, 7.0, 8.0]
def test_swapaxis_traceidcodes(): cube = Cube( xori=0.0, yori=0.0, zori=0.0, ncol=2, nrow=2, nlay=2, xinc=1.0, yinc=1.0, zinc=1.0, yflip=1, values=[1, 2, 3, 4, 5, 6, 7, 8], ) assert cube.traceidcodes.flatten().tolist() == [1, 1, 1, 1] cube.traceidcodes = [1, 2, 3, 4] cube.swapaxes() assert cube.traceidcodes.flatten().tolist() == [1, 3, 2, 4]
def test_cube_resampling(loadsfile1): """Import a cube, then make a smaller and resample, then export the new""" logger.info("Import SEGY format via SEGYIO") incube = loadsfile1 newcube = Cube( xori=460500, yori=5926100, zori=1540, xinc=40, yinc=40, zinc=5, ncol=200, nrow=100, nlay=100, rotation=incube.rotation, yflip=incube.yflip, ) newcube.resample(incube, sampling="trilinear", outside_value=10.0) tsetup.assert_almostequal(newcube.values.mean(), 5.3107, 0.0001) tsetup.assert_almostequal(newcube.values[20, 20, 20], 10.0, 0.0001) newcube.to_file(join(TMD, "cube_resmaple1.segy"))
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", )
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')
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()
def test_cube_thinning(tmpdir, loadsfile1): """Import a cube, then make a smaller by thinning every N line""" logger.info("Import SEGY format via SEGYIO") incube = loadsfile1 logger.info(incube) # thinning to evey second column and row, but not vertically incube.do_thinning(2, 2, 1) logger.info(incube) incube.to_file(join(tmpdir, "cube_thinned.segy")) incube2 = Cube(join(tmpdir, "cube_thinned.segy")) logger.info(incube2)
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
def test_cube_swapaxes(): """Import a cube, do axes swapping back and forth""" logger.info("Import SEGY format via SEGYIO") incube = Cube(SFILE4) logger.info(incube) val1 = incube.values.copy() incube.swapaxes() logger.info(incube) incube.swapaxes() val2 = incube.values.copy() logger.info(incube) np.testing.assert_array_equal(val1, val2)
def test_storm_import(): """Import Cube using Storm format (case Reek).""" acube = Cube() st1 = xtg.timer() acube.from_file(SFILE3, fformat="storm") elapsed = xtg.timer(st1) logger.info("Reading Storm format took %s", elapsed) assert acube.ncol == 280, "NCOL" vals = acube.values tsetup.assert_almostequal(vals[180, 185, 4], 0.117074, 0.0001) acube.to_file(join(TMD, "cube.rmsreg"), fformat="rms_regular")
def test_storm_import(tmpdir): """Import Cube using Storm format (case Reek).""" acube = Cube() st1 = xtg.timer() acube.from_file(SFILE3, fformat="storm") elapsed = xtg.timer(st1) logger.info("Reading Storm format took %s", elapsed) assert acube.ncol == 280, "NCOL" vals = acube.values assert vals[180, 185, 4] == pytest.approx(0.117074, 0.0001) acube.to_file(join(tmpdir, "cube.rmsreg"), fformat="rms_regular")
def test_segyio_export_xtgeo(loadsfile1): """Import via SEGYIO and and export SEGY (case 1 Reek) via XTGeo.""" logger.info("Import SEGY format via SEGYIO") xcu = loadsfile1 xcu.values += 200 xcu.to_file(join(TMD, "reek_cube_xtgeo.segy"), engine="xtgeo") xxcu = Cube() xxcu.scan_segy_header(join(TMD, "reek_cube_xtgeo.segy"), outfile=join(TMD, "cube_scanheader2")) xxcu.scan_segy_traces(join(TMD, "reek_cube_xtgeo.segy"), outfile=join(TMD, "cube_scantraces2"))
def test_cube_swapaxes(): """Import a cube, do axes swapping back and forth""" logger.info("Import SEGY format via SEGYIO") incube = Cube(SFILE4) logger.info(incube) val1 = incube.values.copy() incube.swapaxes() logger.info(incube) incube.swapaxes() val2 = incube.values.copy() logger.info(incube) diff = val1 - val2 tsetup.assert_almostequal(diff.mean(), 0.0, 0.000001) tsetup.assert_almostequal(diff.std(), 0.0, 0.000001) assert incube.ilines.size == incube.ncol
def test_segy_no_file_exception(): with pytest.raises(xtgeo.XTGeoCLibError, match="Could not open file"): Cube().scan_segy_traces("not_a_file", outfile="not_relevant")
def test_segy_scantraces(tmpdir): """Scan and report SEGY first and last trace (internal reader).""" Cube().scan_segy_traces(SFILE1, outfile=join(tmpdir, "cube_scantraces"))