def test_undef(): """Test getting UNDEF value""" xx = GridProperty() act = xx.get_actnum() assert xx.undef == xtgeo.UNDEF assert act.undef == xtgeo.UNDEF_INT
def test_grdecl_import_reek(): """Property GRDECL import from Eclipse. Reek""" rgrid = Grid(testfile12a, fformat='grdecl') assert rgrid.dimensions == (40, 64, 14) poro = GridProperty(testfile12b, name='PORO', fformat='grdecl', grid=rgrid) poro2 = GridProperty(testfile1, name='PORO', fformat='roff', grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), poro2.values.mean(), 0.001) tsetup.assert_almostequal(poro.values.std(), poro2.values.std(), 0.001) with pytest.raises(KeywordNotFoundError): poro3 = GridProperty(testfile12b, name='XPORO', fformat='grdecl', grid=rgrid) logger.debug('Keyword failed as expected for instance %s', poro3) # Export to ascii grdecl and import that again... exportfile = os.path.join(td, 'reekporo.grdecl') poro.to_file(exportfile, fformat='grdecl') porox = GridProperty(exportfile, name='PORO', fformat='grdecl', grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), porox.values.mean(), 0.001) # Export to binary grdecl and import that again... exportfile = os.path.join(td, 'reekporo.bgrdecl') poro.to_file(exportfile, fformat='bgrdecl') porox = GridProperty(exportfile, name='PORO', fformat='bgrdecl', grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), porox.values.mean(), 0.001)
def test_eclunrst_import_soil_reek(): """Property UNRST import from Eclipse, computing SOIL. Reek""" gg = Grid(TESTFILE5, fformat="egrid") logger.info("Import RESTART (UNIFIED) ...") swat = GridProperty(TESTFILE7, name="SWAT", fformat="unrst", date=19991201, grid=gg) tsetup.assert_almostequal(swat.values.mean(), 0.8780, 0.001) sgas = GridProperty(TESTFILE7, name="SGAS", fformat="unrst", date=19991201, grid=gg) tsetup.assert_almostequal(sgas.values.mean(), 0.000, 0.001) soil = GridProperty(TESTFILE7, name="SOIL", fformat="unrst", date=19991201, grid=gg) tsetup.assert_almostequal(soil.values.mean(), 1.0 - 0.8780, 0.001)
def test_io_roff_discrete(): """Import ROFF discrete property; then export to ROFF int.""" logger.info("Name is {}".format(__name__)) po = GridProperty() po.from_file(TESTFILE8, fformat="roff", name="Zone") logger.info("\nCodes ({})\n{}".format(po.ncodes, po.codes)) # tests: assert po.ncodes == 3 logger.debug(po.codes[3]) assert po.codes[3] == "Below_Low_reek" # export discrete to ROFF ...TODO po.to_file(os.path.join(TMPDIR, "reek_zone_export.roff"), name="Zone", fformat="roff") # fix some zero values (will not be fixed properly as grid ACTNUM differs?) val = po.values val = npma.filled(val, fill_value=3) # trick print(val.min(), val.max()) po.values = val print(po.values.min(), po.values.max()) po.values[:, :, 13] = 1 # just for fun test po.to_file(os.path.join(TMPDIR, "reek_zonefix_export.roff"), name="ZoneFix", fformat="roff")
def test_grdecl_import_reek(): """Property GRDECL import from Eclipse. Reek""" rgrid = Grid(TESTFILE12A, fformat="grdecl") assert rgrid.dimensions == (40, 64, 14) poro = GridProperty(TESTFILE12B, name="PORO", fformat="grdecl", grid=rgrid) poro2 = GridProperty(TESTFILE1, name="PORO", fformat="roff", grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), poro2.values.mean(), 0.001) tsetup.assert_almostequal(poro.values.std(), poro2.values.std(), 0.001) with pytest.raises(KeywordNotFoundError): poro3 = GridProperty(TESTFILE12B, name="XPORO", fformat="grdecl", grid=rgrid) logger.debug("Keyword failed as expected for instance %s", poro3) # Export to ascii grdecl and import that again... exportfile = os.path.join(TMPDIR, "reekporo.grdecl") poro.to_file(exportfile, fformat="grdecl") porox = GridProperty(exportfile, name="PORO", fformat="grdecl", grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), porox.values.mean(), 0.001) # Export to binary grdecl and import that again... exportfile = os.path.join(TMPDIR, "reekporo.bgrdecl") poro.to_file(exportfile, fformat="bgrdecl") porox = GridProperty(exportfile, name="PORO", fformat="bgrdecl", grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), porox.values.mean(), 0.001)
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)
def test_eclunrst_import_soil_reek(): """Property UNRST import from Eclipse, computing SOIL. Reek""" gg = Grid(testfile5, fformat='egrid') logger.info("Import RESTART (UNIFIED) ...") swat = GridProperty(testfile7, name='SWAT', fformat='unrst', date=19991201, grid=gg) tsetup.assert_almostequal(swat.values.mean(), 0.8780, 0.001) sgas = GridProperty(testfile7, name='SGAS', fformat='unrst', date=19991201, grid=gg) tsetup.assert_almostequal(sgas.values.mean(), 0.000, 0.001) soil = GridProperty(testfile7, name='SOIL', fformat='unrst', date=19991201, grid=gg) tsetup.assert_almostequal(soil.values.mean(), 1.0 - 0.8780, 0.001)
def test_create(): """Create a simple property""" x = GridProperty() assert x.ncol == 5, 'NCOL' assert x.nrow == 12, 'NROW' m = GridProperty(discrete=True) (repr(m.values))
def test_roffbin_import1_new(): """Test ROFF import, new code May 2018""" logger.info("Name is {}".format(__name__)) x = GridProperty() logger.info("Import roff...") x.from_file(TESTFILE1, fformat="roff", name="PORO") logger.info("Porosity is {}".format(x.values)) logger.info("Mean porosity is {}".format(x.values.mean()))
def test_create(): """Create a simple property""" x = GridProperty() assert x.ncol == 4, "NCOL" assert x.nrow == 3, "NROW" m = GridProperty(discrete=True) (repr(m.values))
def test_get_xy_values_for_webportal_ecl(): """Get lists on webportal format (Eclipse input)""" grid = Grid(TESTFILE5) prop = GridProperty(TESTFILE6, grid=grid, name="PORO") coord, _valuelist = prop.get_xy_value_lists(grid=grid) logger.info("First active cell coords\n{}.".format(coord[0][0])) tsetup.assert_almostequal(coord[0][0][0][1], 5935688.22412, 0.001)
def _import_field_param(input_grid, param_name, files): grid_param = Grid(input_grid.rsplit(".", 1)[0], fformat="eclipserun") all_input = [] for file_path in files: proproff = GridProperty(file_path, name=param_name, grid=grid_param) array_nb = proproff.get_npvalues1d(activeonly=False, fill_value=0, order="C") all_input.append(array_nb) return all_input
def test_gridprop_to_from_file_is_identity(tmp_path, grid, data): filepath = tmp_path / "gridprop.grdecl" prop = data.draw(st.sampled_from(grid.get_xyz_corners())) prop.to_file(filepath, fformat="grdecl") prop_from_file = GridProperty().from_file( filepath, name=prop.name, fformat="grdecl", grid=grid ) assert_allclose(prop.get_npvalues1d(), prop_from_file.get_npvalues1d(), atol=1e-3)
def test_create_actnum(): """Test creating ACTNUM""" x = GridProperty() act = x.get_actnum() print(x.values) print(act.values) print(x.nactive) print(x.ntotal) assert x.nactive < x.ntotal
def test_eclinit_simple_importexport(): """Property import and export with anoother name""" # let me guess the format (shall be egrid) gg = Grid(TESTFILE13A, fformat="egrid") po = GridProperty(TESTFILE13B, name="PORO", grid=gg) po.to_file(os.path.join(TMPDIR, "simple.grdecl"), fformat="grdecl", name="PORO2") p2 = GridProperty(os.path.join(TMPDIR, "simple.grdecl"), grid=gg, name="PORO2") assert p2.name == "PORO2"
def test_eclinit_simple_importexport(): """Property import and export with anoother name""" # let me guess the format (shall be egrid) gg = Grid(testfile13a, fformat='egrid') po = GridProperty(testfile13b, name='PORO', grid=gg) po.to_file(os.path.join(td, "simple.grdecl"), fformat="grdecl", name="PORO2") p2 = GridProperty(os.path.join(td, "simple.grdecl"), grid=gg, name="PORO2") assert p2.name == "PORO2"
def test_gridprop_to_from_file_is_identity(tmp_path, grid): filepath = tmp_path / "gridprop.grdecl" for prop in grid.get_xyz_corners(): prop.to_file(filepath, fformat="grdecl") prop_from_file = GridProperty().from_file(filepath, name=prop.name, fformat="grdecl", grid=grid) assert_allclose(prop.get_npvalues1d(), prop_from_file.get_npvalues1d(), atol=1e-3)
def test_values_in_polygon(): """Test replace values in polygons""" xprop = GridProperty() logger.info("Import roff...") grid = Grid(TESTFILE5) xprop.from_file(TESTFILE1, fformat="roff", name="PORO", grid=grid) poly = Polygons(POLYFILE) xprop.geometry = grid xorig = xprop.copy() xprop.operation_polygons(poly, 99, inside=True) tsetup.assert_almostequal(xprop.values.mean(), 25.1788, 0.01) xp2 = xorig.copy() xp2.values *= 100 xp2.continuous_to_discrete() xp2.set_inside(poly, 44) xp2.dtype = np.uint8 xp2.set_inside(poly, 44) print(xp2.values) xp2.dtype = np.uint16 xp2.set_inside(poly, 44) print(xp2.values) xp3 = xorig.copy() xp3.values *= 100 print(xp3.values.mean()) xp3.dtype = np.float32 xp3.set_inside(poly, 44) print(xp3.values.mean()) tsetup.assert_almostequal(xp3.values.mean(), 23.40642788381048, 0.001)
def test_roffbin_import2_roffapiv2(): """Import roffbin, with several props in one file. API version 2""" logger.info("Name is {}".format(__name__)) dz = GridProperty() logger.info("Import roff...") dz.from_file(TESTFILE2, fformat="roff", name="Z_increment", _roffapiv=2) logger.info(repr(dz.values)) logger.info(dz.values.dtype) logger.info("Mean DZ is {}".format(dz.values.mean())) hc = GridProperty() logger.info("Import roff...") hc.from_file(TESTFILE2, fformat="roff", name="Oil_HCPV", _roffapiv=2) logger.info(repr(hc.values)) logger.info(hc.values.dtype) logger.info(hc.values3d.shape) _ncol, nrow, _nlay = hc.values3d.shape assert nrow == 100, "NROW from shape (Emerald)" logger.info("Mean HCPV is {}".format(hc.values.mean())) tsetup.assert_almostequal(hc.values.mean(), 1446.4611912446985, 0.0001)
def test_roffbin_import2(): """Import roffbin, with several props in one file.""" logger.info('Name is {}'.format(__name__)) dz = GridProperty() logger.info("Import roff...") dz.from_file(testfile2, fformat="roff", name='Z_increment') logger.info(repr(dz.values)) logger.info(dz.values.dtype) logger.info("Mean DZ is {}".format(dz.values.mean())) hc = GridProperty() logger.info("Import roff...") hc.from_file(testfile2, fformat="roff", name='Oil_HCPV') logger.info(repr(hc.values)) logger.info(hc.values.dtype) logger.info(hc.values3d.shape) _ncol, nrow, _nlay = hc.values3d.shape assert nrow == 100, 'NROW from shape (Emerald)' logger.info("Mean HCPV is {}".format(hc.values.mean())) tsetup.assert_almostequal(hc.values.mean(), 1446.4611912446985, 0.0001)
def test_roffbin_import1_roffapiv2(): """Test of import of ROFF binary using new API""" logger.info("Name is {}".format(__name__)) x = GridProperty() logger.info("Import roff...") x.from_file(TESTFILE1, fformat="roff", name="PORO", _roffapiv=2) logger.info(repr(x.values)) logger.info(x.values.dtype) logger.info("Porosity is {}".format(x.values)) logger.info("Mean porosity is {}".format(x.values.mean())) assert x.values.mean() == pytest.approx(0.1677, abs=0.001)
def test_roffbin_import1(): """Test of import of ROFF binary""" logger.info('Name is {}'.format(__name__)) x = GridProperty() logger.info("Import roff...") x.from_file(testfile1, fformat="roff", name='PORO') logger.info(repr(x.values)) logger.info(x.values.dtype) logger.info("Porosity is {}".format(x.values)) logger.info("Mean porosity is {}".format(x.values.mean())) assert x.values.mean() == pytest.approx(0.1677, abs=0.001)
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)
def test_eclinit_import_reek(): """Property import from Eclipse. Reek""" # let me guess the format (shall be egrid) gg = Grid(TESTFILE5, fformat="egrid") assert gg.ncol == 40, "Reek NX" logger.info("Import INIT...") po = GridProperty(TESTFILE6, name="PORO", grid=gg) logger.info(po.values.mean()) assert po.values.mean() == pytest.approx(0.1677, abs=0.0001) pv = GridProperty(TESTFILE6, name="PORV", grid=gg) logger.info(pv.values.mean())
def test_dtype(): """Test dtype property""" xx = GridProperty() act = xx.get_actnum() if not xx.isdiscrete: xx.dtype = np.float16 assert xx.dtype == np.float16 with pytest.raises(ValueError): xx.dtype = np.int32 assert act.dtype == np.int32 with pytest.raises(ValueError): act.dtype = np.float64
def test_banal7(xtgshow): """Create a simple property in a small grid box""" grd = Grid(BANAL7) assert grd.dimensions == (4, 2, 3) disc = GridProperty(BANAL7, name="DISC") assert disc.dimensions == (4, 2, 3) assert disc.values.mean() == pytest.approx(0.59091, abs=0.001) gprops = grd.get_gridquality_properties() mix = gprops.get_prop_by_name("minangle_sides") assert mix.values.mean() == pytest.approx(81.31036, abs=0.001) if xtgshow: lay = 2 layslice = xtgeo.plot.Grid3DSlice() layslice.canvas(title=f"Layer {lay}") layslice.plot_gridslice( grd, prop=mix, mode="layer", index=lay, window=None, linecolor="black", ) layslice.show()
def test_get_values_by_ijk(): """Test getting values for given input arrays for I J K""" logger.info("Name is {}".format(__name__)) x = GridProperty() logger.info("Import roff...") x.from_file(TESTFILE1, fformat="roff", name="PORO") iset1 = np.array([np.nan, 23, 22]) jset1 = np.array([np.nan, 23, 19]) kset1 = np.array([np.nan, 13, 2]) res1 = x.get_values_by_ijk(iset1, jset1, kset1) tsetup.assert_almostequal(res1[1], 0.08403542, 0.0001) assert np.isnan(res1[0])
def test_refine_vertically_per_zone(tmpdir): """Do a grid refinement vertically, via a dict per zone.""" logger.info("Read grid...") grd_orig = Grid(EMEGFILE2) grd = grd_orig.copy() logger.info("Read grid... done, NLAY is {}".format(grd.nlay)) grd.to_file(join(tmpdir, "test_refined_by_dict_initial.roff")) logger.info("Subgrids before: %s", grd.get_subgrids()) zone = GridProperty(EMEZFILE2, grid=grd, name="Zone") logger.info("Zone values min max: %s %s", zone.values.min(), zone.values.max()) logger.info("Subgrids list: %s", grd.subgrids) refinement = {1: 4, 2: 2} grd.refine_vertically(refinement, zoneprop=zone) grd1s = grd.get_subgrids() logger.info("Subgrids after: %s", grd1s) grd.to_file(join(tmpdir, "test_refined_by_dict.roff")) grd = grd_orig.copy() grd.refine_vertically(refinement) # no zoneprop grd2s = grd.get_subgrids() logger.info("Subgrids after: %s", grd2s) assert list(grd1s.values()) == list(grd2s.values())
def test_crop_grid_after_copy(): """Copy a grid, then crop and check number of active cells.""" logger.info("Read grid...") grd = Grid(EMEGFILE2) grd.describe() zprop = GridProperty(EMEZFILE2, name="Zone", grid=grd) grd.describe(details=True) logger.info(grd.dimensions) grd2 = grd.copy() grd2.describe(details=True) logger.info("GRD2 props: %s", grd2.props) assert grd.propnames == grd2.propnames logger.info("GRD2 number of active cells: %s", grd2.nactive) act = grd.get_actnum() logger.info(act.values.shape) logger.info("ZPROP: %s", zprop.values.shape) grd2.crop((1, 30), (40, 80), (23, 46)) grd2.describe(details=True)
def test_slice_simple_layer(): """Trigger XSection class, and do some simple things basically.""" layslice = Grid3DSlice() mygrid = Grid(USEFILE1) myprop = GridProperty(USEFILE2, grid=mygrid, name="PORO") assert myprop.values.mean() == pytest.approx(0.1677, abs=0.001) wd = None # [457000, 464000, 1650, 1800] for lay in range(1, mygrid.nlay + 1): layslice.canvas(title="My Grid Layer plot for layer {}".format(lay)) layslice.plot_gridslice(mygrid, prop=myprop, mode="layer", index=lay, window=wd) if XTGSHOW: layslice.show() else: print("Output to screen disabled (will plot to screen); " "use XTG_SHOW env variable") layslice.savefig( os.path.join(TMPDIR, "layerslice_" + str(lay) + ".png"))