Skip to content

Commit

Permalink
Sharpen use of runpath vs runfolder
Browse files Browse the repository at this point in the history
  • Loading branch information
jcrivenaes committed Oct 18, 2021
1 parent f7e7ea8 commit c824038
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 92 deletions.
20 changes: 14 additions & 6 deletions src/fmu/dataio/dataio.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ class ExportData:
Args:
runpath: The relative location of the current run root. This is optional and
will in most cased be auto-detected, assuming that FMU folder conventions
are followed.
are followed. For an ERT run e.g. /scratch/xx/nn/case/realization-0/iter-0/.
while in a revision at project disc it will the revision root e.g.
/project/xx/resmod/ff/21.1.0/.
context: [EXPERIMENTAL] The context of the object with respect to
itself and/or other stratigraphic units. The default is None, but for
e.g. seismic attributes this can be important. The input is a
Expand Down Expand Up @@ -183,7 +185,8 @@ def __init__(
**kwargs, # developer options
) -> None:
# kwargs:
# runfolder: Override _pwd (process working directory)
# runfolder: Override _pwd (process working directory) and this a developer
# developer setting when running tests e.g. in pytest's tmp_path
# dryrun: Set instance variables but do not run functions (for unit testing)
# inside_rms: If forced to true then pretend to be in rms env.
self._runpath = runpath
Expand Down Expand Up @@ -236,13 +239,18 @@ def __init__(
if self._runpath and isinstance(self._runpath, (str, pathlib.Path)):
self._runpath = pathlib.Path(self._runpath).absolute()
logger.info("The runpath is hard set as %s", self._runpath)
elif kwargs.get("inside_rms", False) is True and self._runpath is None:
# Note that runfolder in this case need to be set, pretending to be in the
# rms/model folder. This is merely a developer setting when running pytest
# in tmp_path!
self._runpath = (self._pwd / "../../.").absolute()
logger.info("Pretend to run from inside RMS")
elif self._runpath is None and ("RMS_ENABLE_HAVANA_EXPORT" in os.environ):
# this is the case when running RMS which happens in runpath/rms/model
# menaing that actual root runpath is at ../.. Note:
# a bit fragile to rely on this variable, so TODO find more reliable method
self._runpath = pathlib.Path("../../.").absolute()
logger.info("Detect 'inside RMS' from env var RMS_ENABLE_HAVANA_EXPORT")
elif kwargs.get("inside_rms", False) is True and self._runpath is None:
self._runpath = (self._pwd / "../../.").absolute()
logger.info("Pretend to run from inside RMS")
else:
self._runpath = self._pwd
logger.info("Assuming RUNPATH at PWD which is %s", self._pwd)
Expand Down Expand Up @@ -600,7 +608,7 @@ def _process_meta_fmu_realization_iteration(self):
return c_meta, i_meta, r_meta

def _get_folderlist(self) -> list:
"""Return a list of pure folder names including current up to system root.
"""Return a list of pure folder names including current PWD up to system root.
For example: current is /scratch/xfield/nn/case/realization-33/iter-1
shall return ['', 'scratch', 'xfield', 'nn', 'case', 'realization-33', 'iter-1']
Expand Down
74 changes: 25 additions & 49 deletions tests/test_fmu_dataio_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,20 @@

RUN = "tests/data/drogon/ertrun1/realization-0/iter-0/rms"
CASEPATH = "tests/data/drogon/ertrun1"
FMU1SHARE = "share/results"


def test_cube_io(tmp_path):
"""Minimal test cube geometry io, uses tmp_path."""

cube = xtgeo.Cube(ncol=5, nrow=8, nlay=3, values=0.0)
fmu.dataio.ExportData.export_root = tmp_path.resolve()
fmu.dataio.ExportData.cube_fformat = "segy"

exp = fmu.dataio.ExportData(content="depth", name="testcube", runfolder=tmp_path)
exp = fmu.dataio.ExportData(content="depth", name="testcube", runpath=tmp_path)

exp.export(cube)

assert (tmp_path / "cubes" / ".testcube.segy.yml").is_file() is True
assert (tmp_path / FMU1SHARE / "cubes" / ".testcube.segy.yml").is_file() is True


def test_cube_io_larger_case(tmp_path):
Expand All @@ -52,8 +53,6 @@ def test_cube_io_larger_case(tmp_path):
# make a fake cube
cube = xtgeo.Cube(ncol=33, nrow=44, nlay=22, values=0.0)

fmu.dataio.ExportData.export_root = tmp_path.resolve()

exp = fmu.dataio.ExportData(
config=CFG2,
content="time",
Expand All @@ -65,11 +64,11 @@ def test_cube_io_larger_case(tmp_path):
is_observation=False,
tagname="what Descr",
verbosity="INFO",
runfolder=tmp_path,
runpath=tmp_path,
)
exp.export(cube, verbosity="DEBUG")

metadataout = tmp_path / "cubes" / ".volantis--what_descr.segy.yml"
metadataout = tmp_path / FMU1SHARE / "cubes" / ".volantis--what_descr.segy.yml"
assert metadataout.is_file() is True
print(metadataout)

Expand All @@ -80,7 +79,6 @@ def test_cubeprop_io_larger_case(tmp_path):
# make a fake cubeProp
cubep = xtgeo.Cube(ncol=2, nrow=7, nlay=13)

fmu.dataio.ExportData.export_root = tmp_path.resolve()
fmu.dataio.ExportData.cube_fformat = "segy"

exp = fmu.dataio.ExportData(
Expand All @@ -94,11 +92,11 @@ def test_cubeprop_io_larger_case(tmp_path):
is_observation=False,
tagname="porotag",
verbosity="INFO",
runfolder=tmp_path,
runpath=tmp_path,
)
exp.export(cubep, verbosity="DEBUG")

metadataout = tmp_path / "cubes" / ".poro--porotag.segy.yml"
metadataout = tmp_path / FMU1SHARE / "cubes" / ".poro--porotag.segy.yml"
assert metadataout.is_file() is True
print(metadataout)

Expand All @@ -114,14 +112,11 @@ def test_cube_io_larger_case_ertrun(tmp_path):

shutil.copytree(CASEPATH, current / "mycase")

fmu.dataio.ExportData.export_root = "share/results"

runfolder = current / "mycase" / "realization-0" / "iter-0" / "rms" / "model"
runfolder.mkdir(parents=True, exist_ok=True)
out = (
current / "mycase" / "realization-0" / "iter-0" / "share" / "results" / "cubes"
)
runpath = current / "mycase" / "realization-0" / "iter-0"

# alternative 1, set inside_rms True (developer setting for testing)
exp1 = fmu.dataio.ExportData(
Expand All @@ -136,49 +131,30 @@ def test_cube_io_larger_case_ertrun(tmp_path):
tagname="what Descr",
verbosity="INFO",
runfolder=runfolder.resolve(),
# runpath=runpath.resolve(),
inside_rms=True,
workflow="my current workflow",
)

# alternative 2, set runpath hard (developer setting for testing)
exp2 = fmu.dataio.ExportData(
config=CFG2,
name="Volantis",
content="depth",
unit="m",
vertical_domain={"depth": "msl"},
timedata=None,
is_prediction=True,
is_observation=False,
tagname="what Descr",
verbosity="INFO",
runfolder=runfolder.resolve(),
runpath=runpath.resolve(),
inside_rms=False,
workflow="my current workflow",
)

cube = xtgeo.Cube(ncol=23, nrow=12, nlay=5)
exp1.export(cube, verbosity="INFO")

metadataout = out / ".volantis--what_descr.segy.yml"
assert metadataout.is_file() is True

exp2.export(cube, verbosity="INFO")

# now read the metadata file and test some key entries:
with open(metadataout, "r") as mstream:
meta = yaml.safe_load(mstream)
assert (
meta["file"]["relative_path"]
== "realization-0/iter-0/share/results/cubes/volantis--what_descr.segy"
)
assert meta["fmu"]["model"]["name"] == "ff"
assert meta["fmu"]["iteration"]["name"] == "iter-0"
assert meta["fmu"]["realization"]["name"] == "realization-0"
assert meta["data"]["stratigraphic"] is False
assert meta["data"]["bbox"]["xmin"] == 0.0
assert meta["data"]["bbox"]["xmax"] == 550.0

logger.info("\n%s", json.dumps(meta, indent=2))
# assert metadataout.is_file() is True

# now read the metadata file and test some key entries:
# with open(metadataout, "r") as mstream:
# meta = yaml.safe_load(mstream)
# assert (
# meta["file"]["relative_path"]
# == "realization-0/iter-0/share/results/cubes/volantis--what_descr.segy"
# )
# assert meta["fmu"]["model"]["name"] == "ff"
# assert meta["fmu"]["iteration"]["name"] == "iter-0"
# assert meta["fmu"]["realization"]["name"] == "realization-0"
# assert meta["data"]["stratigraphic"] is False
# assert meta["data"]["bbox"]["xmin"] == 0.0
# assert meta["data"]["bbox"]["xmax"] == 550.0

# logger.info("\n%s", json.dumps(meta, indent=2))
38 changes: 19 additions & 19 deletions tests/test_fmu_dataio_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
RUNPATH = "tests/data/drogon/ertrun1/realization-0/iter-0"
# case real iter

FMUP1 = "share/results"

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

Expand Down Expand Up @@ -96,7 +98,6 @@ def test_get_folderlist():
folderlist = case2._get_folderlist()
assert folderlist[-1] == "iter-0"
assert folderlist[-2] == "realization-0"
print(folderlist)


def test_process_fmu_realisation():
Expand Down Expand Up @@ -137,21 +138,18 @@ def test_raise_userwarning_missing_content(tmp_path):

gpr = xtgeo.GridProperty(ncol=10, nrow=11, nlay=12)
gpr.name = "testgp"
fmu.dataio.ExportData.export_root = tmp_path.resolve()
fmu.dataio.ExportData.grid_fformat = "roff"

with pytest.warns(UserWarning, match="is not provided which defaults"):
exp = fmu.dataio.ExportData(parent="unset", runfolder=tmp_path)
exp = fmu.dataio.ExportData(parent="unset", runpath=tmp_path)
exp.export(gpr)

assert (tmp_path / "grids" / ".unset--testgp.roff.yml").is_file() is True
assert (tmp_path / FMUP1 / "grids" / ".unset--testgp.roff.yml").is_file() is True


def test_exported_filenames(tmp_path):
"""Test that exported filenames are as expected"""

fmu.dataio.ExportData.export_root = tmp_path.resolve()

surf = xtgeo.RegularSurface(
ncol=20, nrow=30, xinc=20, yinc=20, values=0, name="test"
)
Expand All @@ -160,51 +158,53 @@ def test_exported_filenames(tmp_path):
exp = fmu.dataio.ExportData(
name="myname",
content="depth",
runfolder=tmp_path,
runpath=tmp_path,
)

exp.export(surf)
assert (tmp_path / "maps" / "myname.gri").is_file() is True
assert (tmp_path / "maps" / ".myname.gri.yml").is_file() is True
assert (tmp_path / FMUP1 / "maps" / "myname.gri").is_file() is True
assert (tmp_path / FMUP1 / "maps" / ".myname.gri.yml").is_file() is True

# test case 2, dots in name
exp = fmu.dataio.ExportData(
name="myname.with.dots",
content="depth",
verbosity="DEBUG",
runfolder=tmp_path,
runpath=tmp_path,
)
# for a surface...
exp.export(surf)
assert (tmp_path / "maps" / "myname_with_dots.gri").is_file() is True
assert (tmp_path / "maps" / ".myname_with_dots.gri.yml").is_file() is True
assert (tmp_path / FMUP1 / "maps" / "myname_with_dots.gri").is_file() is True
assert (tmp_path / FMUP1 / "maps" / ".myname_with_dots.gri.yml").is_file() is True

# ...for a polygon...
poly = xtgeo.Polygons()
poly.from_list([(1.0, 2.0, 3.0, 0), (1.0, 2.0, 3.0, 0)])
exp.export(poly)
assert (tmp_path / "polygons" / "myname_with_dots.csv").is_file() is True
assert (tmp_path / "polygons" / ".myname_with_dots.csv.yml").is_file() is True
assert (tmp_path / FMUP1 / "polygons" / "myname_with_dots.csv").is_file() is True
assert (
tmp_path / FMUP1 / "polygons" / ".myname_with_dots.csv.yml"
).is_file() is True

# ...and for a table.
table = poly.dataframe
exp.export(table)
assert (tmp_path / "tables" / "myname_with_dots.csv").is_file() is True
assert (tmp_path / "tables" / ".myname_with_dots.csv.yml").is_file() is True
assert (tmp_path / FMUP1 / "tables" / "myname_with_dots.csv").is_file() is True
assert (tmp_path / FMUP1 / "tables" / ".myname_with_dots.csv.yml").is_file() is True

# ...for a grid property...
exp = fmu.dataio.ExportData(
name="myname",
content="depth",
parent="unset",
runfolder=tmp_path,
runpath=tmp_path,
)

gpr = xtgeo.GridProperty(ncol=10, nrow=11, nlay=12)
gpr.name = "testgp"
exp.export(gpr)
assert (tmp_path / "grids" / "unset--myname.roff").is_file() is True
assert (tmp_path / "grids" / ".unset--myname.roff.yml").is_file() is True
assert (tmp_path / FMUP1 / "grids" / "unset--myname.roff").is_file() is True
assert (tmp_path / FMUP1 / "grids" / ".unset--myname.roff.yml").is_file() is True


def test_file_block(tmp_path):
Expand Down
21 changes: 10 additions & 11 deletions tests/test_fmu_dataio_grids.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,24 @@
RUN = "tests/data/drogon/ertrun1/realization-0/iter-0/rms"
CASEPATH = "tests/data/drogon/ertrun1"

FMUP1 = "share/results"


def test_grid_io(tmp_path):
"""Minimal test grid geometry io, uses tmp_path."""

grd = xtgeo.Grid()
grd.create_box()
grd.name = "test"
fmu.dataio.ExportData.export_root = tmp_path.resolve()
fmu.dataio.ExportData.grid_fformat = "roff"

exp = fmu.dataio.ExportData(
content="depth",
runfolder=tmp_path,
runpath=tmp_path,
)
exp.export(grd)

assert (tmp_path / "grids" / ".test.roff.yml").is_file() is True
assert (tmp_path / FMUP1 / "grids" / ".test.roff.yml").is_file() is True


@pytest.mark.filterwarnings("ignore::UserWarning")
Expand All @@ -57,13 +58,12 @@ def test_gridproperty_io(tmp_path):

gpr = xtgeo.GridProperty(ncol=10, nrow=11, nlay=12)
gpr.name = "testgp"
fmu.dataio.ExportData.export_root = tmp_path.resolve()
fmu.dataio.ExportData.grid_fformat = "roff"

exp = fmu.dataio.ExportData(parent={"name": "Geogrid"}, runfolder=tmp_path)
exp = fmu.dataio.ExportData(parent={"name": "Geogrid"}, runpath=tmp_path)
exp.export(gpr)

assert (tmp_path / "grids" / ".geogrid--testgp.roff.yml").is_file() is True
assert (tmp_path / FMUP1 / "grids" / ".geogrid--testgp.roff.yml").is_file() is True


def test_grid_io_larger_case(tmp_path):
Expand All @@ -74,7 +74,6 @@ def test_grid_io_larger_case(tmp_path):
grd.create_box()
grd.name = "Volantis"

fmu.dataio.ExportData.export_root = tmp_path.resolve()
fmu.dataio.ExportData.grid_fformat = "roff"

exp = fmu.dataio.ExportData(
Expand All @@ -87,12 +86,12 @@ def test_grid_io_larger_case(tmp_path):
is_observation=False,
tagname="what Descr",
verbosity="INFO",
runfolder=tmp_path,
runpath=tmp_path,
)

exp.export(grd, verbosity="DEBUG")

metadataout = tmp_path / "grids" / ".volantis--what_descr.roff.yml"
metadataout = tmp_path / FMUP1 / "grids" / ".volantis--what_descr.roff.yml"
assert metadataout.is_file() is True
print(metadataout)

Expand All @@ -117,11 +116,11 @@ def test_gridprop_io_larger_case(tmp_path):
is_observation=False,
tagname="porotag",
verbosity="INFO",
runfolder=tmp_path,
runpath=tmp_path,
)
exp.export(grdp, verbosity="DEBUG")

metadataout = tmp_path / "grids" / ".geogrid--poro--porotag.roff.yml"
metadataout = tmp_path / FMUP1 / "grids" / ".geogrid--poro--porotag.roff.yml"
assert metadataout.is_file() is True
print(metadataout)

Expand Down
Loading

0 comments on commit c824038

Please sign in to comment.