res2df 1.2.3__tar.gz → 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {res2df-1.2.3 → res2df-1.3.0}/.github/workflows/codecov.yml +2 -2
- {res2df-1.2.3 → res2df-1.3.0}/.github/workflows/res2df.yml +4 -19
- {res2df-1.2.3 → res2df-1.3.0}/.pre-commit-config.yaml +2 -2
- res2df-1.3.0/CONTRIBUTING.md +30 -0
- {res2df-1.2.3 → res2df-1.3.0}/PKG-INFO +14 -4
- {res2df-1.2.3 → res2df-1.3.0}/README.md +1 -1
- {res2df-1.2.3 → res2df-1.3.0}/res2df/common.py +9 -8
- {res2df-1.2.3 → res2df-1.3.0}/res2df/compdat.py +3 -6
- {res2df-1.2.3 → res2df-1.3.0}/res2df/csv2res.py +1 -2
- {res2df-1.2.3 → res2df-1.3.0}/res2df/equil.py +1 -1
- {res2df-1.2.3 → res2df-1.3.0}/res2df/grid.py +1 -4
- {res2df-1.2.3 → res2df-1.3.0}/res2df/gruptree.py +15 -2
- {res2df-1.2.3 → res2df-1.3.0}/res2df/rft.py +5 -5
- {res2df-1.2.3 → res2df-1.3.0}/res2df/satfunc.py +8 -7
- {res2df-1.2.3 → res2df-1.3.0}/res2df/summary.py +4 -4
- {res2df-1.2.3 → res2df-1.3.0}/res2df/version.py +2 -2
- {res2df-1.2.3 → res2df-1.3.0}/res2df.egg-info/PKG-INFO +14 -4
- {res2df-1.2.3 → res2df-1.3.0}/res2df.egg-info/SOURCES.txt +1 -0
- {res2df-1.2.3 → res2df-1.3.0}/setup.py +1 -1
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/EIGHTCELLS.DATA +2 -2
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_equil.py +3 -1
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_gruptree.py +14 -14
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_rft.py +15 -8
- {res2df-1.2.3 → res2df-1.3.0}/.codacy.yml +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/.github/workflows/style.yml +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/.github/workflows/typing.yml +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/.gitignore +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/LICENSE +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/SECURITY.md +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/ci/testkomodo.sh +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/_static/equinor-logo.png +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/_static/equinor-logo2.jpg +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/_static/equinor_logo.jpg +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/_static/equinor_logo_only.jpg +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/_templates/layout.html +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/conf.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/contribution.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/csv2res.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/glossary.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/history.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/index.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/installation.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/introduction.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/res2csv.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/compdat.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/compdat.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/equil-example.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/equil.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/fipnum.inc +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/fipreports-example.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/fipreports-example.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/fipreports.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/grid.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/grid.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/gruptree.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/gruptree.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/gruptreenet.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/images/injectoranalysis.png +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/images/multibranch-rftanalysis.png +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/nnc.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/nnc.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/outflow.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/pillars-dyn1-stacked.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/pillars-dyn1-unstacked.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/pillars-example1.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/pillars.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/pvt.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/pvt.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/rft.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/rft_columns.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/satfunc.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/satfunc.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/summary.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/summary.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/trans-boundaries.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/trans-group.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/trans.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/trans1.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/wcon.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/wcon.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/well_connection_status.csv +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage/wellconnstatus.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/docs/usage.rst +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/mypy.ini +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/py.typed +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/__init__.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/__version__.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/config_jobs/CSV2RES +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/config_jobs/RES2CSV +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/constants.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/faults.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/fipreports.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/hook_implementations/__init__.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/hook_implementations/jobs.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/inferdims.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/nnc.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/BRANPROP +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/COMPDAT +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/COMPLUMP +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/COMPSEGS +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/DENSITY +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/EQLDIMS +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/EQUIL +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/FAULTS +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/GRUPNET +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/GRUPTREE +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/NODEPROP +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/PBVD +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/PDVD +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/PVDG +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/PVDO +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/PVTG +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/PVTO +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/PVTW +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/ROCK +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/RSVD +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/RVVD +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/SGFN +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/SGOF +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/SGWFN +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/SLGOF +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/SOF2 +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/SOF3 +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/SWFN +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/SWOF +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/TABDIMS +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/VFPINJ +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/VFPPROD +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WCONHIST +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WCONINJE +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WCONINJH +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WCONPROD +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WELOPEN +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WELSEGS +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WELSPECS +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WLIST +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WSEGAICD +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WSEGSICD +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/WSEGVALV +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/readme +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/opmkeywords/runmetoupdate.sh +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/parameters.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/pillars.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/pvt.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/res2csv.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/res2csvlogger.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/resdatafiles.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/svg_color_keyword_names.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/trans.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/vfp/__init__.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/vfp/_vfp.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/vfp/_vfpcommon.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/vfp/_vfpdefs.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/vfp/_vfpinj.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/vfp/_vfpprod.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/wcon.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/wellcompletiondata.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df/wellconnstatus.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df.egg-info/dependency_links.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df.egg-info/entry_points.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df.egg-info/not-zip-safe +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df.egg-info/requires.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/res2df.egg-info/top_level.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/ruff.toml +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/setup.cfg +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/test_requirements.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/__init__.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/conftest.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/EIGHTCELLS.EGRID +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/EIGHTCELLS.INIT +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/EIGHTCELLS.INSPEC +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/EIGHTCELLS.PRT +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/EIGHTCELLS.RFT +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/EIGHTCELLS.RSSPEC +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/EIGHTCELLS.SMSPEC +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/EIGHTCELLS.UNRST +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/EIGHTCELLS.UNSMRY +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/eightcells_duplicated_summary_vector/EIGHTCELLS_DUPES.DATA +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/eightcells_duplicated_summary_vector/EIGHTCELLS_DUPES.SMSPEC +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/eightcells_duplicated_summary_vector/EIGHTCELLS_DUPES.UNSMRY +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/eightcells/zones.lyr +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/fipreports/TEST1.PRT +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/grid/reek.faults +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/grid/reek.grid +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/grid/reek.multflt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/grid/reek.multz +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/grid/reek.perm +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/grid/reek.poro +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/props/let-sgof.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/props/let-swof.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/props/reek.endpoints +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/props/reek.pvt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/props/reek.swatinit +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/props/sgof.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/props/swof.inc +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/props/swof.txt +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/regions/reek.eqlnum +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/regions/reek.fipnum +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/schedule/op6_aicd1_gp.sch +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/schedule/op6_icd1_gp.sch +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/schedule/op6_valve1_gp.sch +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/schedule/reek_history.sch +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/solution/reek.equil +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/include/summary/reek.smry +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0-OPMFLOW.PRT +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0.DATA +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0.ECLEND +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0.EGRID +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0.INIT +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0.LOG +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0.PRT +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0.RFT +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0.SMSPEC +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0.UNRST +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/2_R001_REEK-0.UNSMRY +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/reek/eclipse/model/zones.lyr +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP.DATA +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP.SMSPEC +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP.UNSMRY +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP_LONG.DATA +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP_LONG.SMSPEC +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP_LONG.UNSMRY +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP.DATA +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP.SMSPEC +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP.UNSMRY +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP_LONG.DATA +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP_LONG.SMSPEC +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP_LONG.UNSMRY +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_common.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_compdat.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_eclfiles.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_ert_hooks.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_faults.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_fipreports.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_grid.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_hook_implementations.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_inferdims.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_init.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_integration.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_logging.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_nnc.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_parameters.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_pillars.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_pvt.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_satfunc.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_summary.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_summary_restarts.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_trans.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_userapi.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_vfp.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_wcon.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_wellcompletiondata.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_wellconnstatus.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_welopen.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_wlist.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/tests/test_zonemap.py +0 -0
- {res2df-1.2.3 → res2df-1.3.0}/types_requirements.txt +0 -0
|
@@ -13,7 +13,7 @@ jobs:
|
|
|
13
13
|
os: [ubuntu-latest]
|
|
14
14
|
env:
|
|
15
15
|
OS: ${{ matrix.os }}
|
|
16
|
-
PYTHON: '3.
|
|
16
|
+
PYTHON: '3.11'
|
|
17
17
|
|
|
18
18
|
steps:
|
|
19
19
|
- uses: actions/checkout@v4
|
|
@@ -21,7 +21,7 @@ jobs:
|
|
|
21
21
|
- name: Setup Python
|
|
22
22
|
uses: actions/setup-python@v5
|
|
23
23
|
with:
|
|
24
|
-
python-version: 3.
|
|
24
|
+
python-version: 3.11
|
|
25
25
|
cache: "pip"
|
|
26
26
|
cache-dependency-path: |
|
|
27
27
|
setup.py
|
|
@@ -19,21 +19,13 @@ jobs:
|
|
|
19
19
|
runs-on: ubuntu-latest
|
|
20
20
|
strategy:
|
|
21
21
|
matrix:
|
|
22
|
-
python-version: ['3.
|
|
23
|
-
pandas-version: ['pandas>2']
|
|
22
|
+
python-version: ['3.11', '3.12']
|
|
24
23
|
include:
|
|
25
24
|
# For one of the Python versions we
|
|
26
25
|
# install the extra dependency ert
|
|
27
26
|
# (in order to not double the job matrix)
|
|
28
|
-
|
|
29
|
-
# Only test with pandas < 2 for py38 and py311
|
|
30
|
-
# No wheels for python3.12 for pandas<2
|
|
31
|
-
- python-version: '3.8'
|
|
32
|
-
install-ert: true
|
|
33
|
-
- python-version: '3.8'
|
|
34
|
-
pandas-version: 'pandas<2'
|
|
35
27
|
- python-version: '3.11'
|
|
36
|
-
|
|
28
|
+
install-ert: true
|
|
37
29
|
|
|
38
30
|
steps:
|
|
39
31
|
- name: Checkout commit locally
|
|
@@ -58,13 +50,6 @@ jobs:
|
|
|
58
50
|
pip install --upgrade pip
|
|
59
51
|
pip install ".[tests, docs]"
|
|
60
52
|
|
|
61
|
-
- name: Install numpy<2 if pandas<2
|
|
62
|
-
if: matrix.pandas-version == 'pandas<2'
|
|
63
|
-
run: pip install "numpy<2"
|
|
64
|
-
|
|
65
|
-
- name: Check pandas version
|
|
66
|
-
run: |
|
|
67
|
-
pip install "${{matrix.pandas-version}}"
|
|
68
53
|
|
|
69
54
|
- name: Install ert
|
|
70
55
|
if: matrix.install-ert
|
|
@@ -87,7 +72,7 @@ jobs:
|
|
|
87
72
|
python setup.py build_sphinx
|
|
88
73
|
|
|
89
74
|
- name: Update GitHub pages
|
|
90
|
-
if: github.repository_owner == 'equinor' && github.ref == 'refs/heads/master' && matrix.python-version == '3.
|
|
75
|
+
if: github.repository_owner == 'equinor' && github.ref == 'refs/heads/master' && matrix.python-version == '3.11'
|
|
91
76
|
run: |
|
|
92
77
|
cp -R ./build/sphinx/html ../html
|
|
93
78
|
|
|
@@ -110,7 +95,7 @@ jobs:
|
|
|
110
95
|
fi
|
|
111
96
|
|
|
112
97
|
- name: Build python package and publish to pypi
|
|
113
|
-
if: github.event_name == 'release' && matrix.python-version == '3.
|
|
98
|
+
if: github.event_name == 'release' && matrix.python-version == '3.11'
|
|
114
99
|
env:
|
|
115
100
|
TWINE_USERNAME: __token__
|
|
116
101
|
TWINE_PASSWORD: ${{ secrets.res2df_pypi_token }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
repos:
|
|
2
2
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
-
rev:
|
|
3
|
+
rev: v5.0.0
|
|
4
4
|
hooks:
|
|
5
5
|
- id: no-commit-to-branch
|
|
6
6
|
args: ['--branch', 'master']
|
|
@@ -13,7 +13,7 @@ repos:
|
|
|
13
13
|
- id: trailing-whitespace
|
|
14
14
|
|
|
15
15
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
16
|
-
rev: v0.
|
|
16
|
+
rev: v0.9.2
|
|
17
17
|
hooks:
|
|
18
18
|
- id: ruff
|
|
19
19
|
args: [ --fix ]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
The following is a set of guidelines for contributing to `res2df`.
|
|
4
|
+
|
|
5
|
+
There are several important ways you can help; here are some examples:
|
|
6
|
+
|
|
7
|
+
- Submitting bug reports and feature requests: see [Issues](https://github.com/equinor/res2df/issues).
|
|
8
|
+
- Proposing code for bug fixes and new features, then [making a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests).
|
|
9
|
+
- Fixing typos and generally improving the documentation.
|
|
10
|
+
- Writing tutorials, examples, and how-to documents.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## Commits
|
|
14
|
+
|
|
15
|
+
We strive to keep a consistent and clean git history and all contributions should adhere to the following:
|
|
16
|
+
|
|
17
|
+
1. All tests should pass on all commits
|
|
18
|
+
1. A commit should do one atomic change on the repository
|
|
19
|
+
1. The commit headline should be descriptive and in the imperative
|
|
20
|
+
|
|
21
|
+
Please note that we use [`black`](https://black.readthedocs.io/en/stable/) and [`isort`](https://pycqa.github.io/isort/) for code formatting.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Pull request process
|
|
25
|
+
|
|
26
|
+
1. Work on your own fork of the main repo.
|
|
27
|
+
1. Push your commits and make a draft pull request using the pull request template.
|
|
28
|
+
1. Check that your pull request passes all tests.
|
|
29
|
+
1. When all tests have passed and your are happy with your changes, change your pull request to "ready for review", and ask for a code review.
|
|
30
|
+
1. When your code has been approved you should rebase, squash and merge your changes.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: res2df
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Convert reservoir simulator input and output to DataFrames
|
|
5
5
|
Home-page: http://github.com/equinor/res2df
|
|
6
6
|
Author: Håvard Berland
|
|
7
7
|
Author-email: havb@equinor.com
|
|
8
8
|
License: GPLv3
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Requires-Dist: resdata>=5.0.0-b0
|
|
@@ -41,10 +41,20 @@ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
|
|
|
41
41
|
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
42
42
|
Provides-Extra: ert
|
|
43
43
|
Requires-Dist: ert>=10.2.0b13; extra == "ert"
|
|
44
|
+
Dynamic: author
|
|
45
|
+
Dynamic: author-email
|
|
46
|
+
Dynamic: description
|
|
47
|
+
Dynamic: description-content-type
|
|
48
|
+
Dynamic: home-page
|
|
49
|
+
Dynamic: license
|
|
50
|
+
Dynamic: provides-extra
|
|
51
|
+
Dynamic: requires-dist
|
|
52
|
+
Dynamic: requires-python
|
|
53
|
+
Dynamic: summary
|
|
44
54
|
|
|
45
55
|
[](https://github.com/equinor/res2df/actions?query=workflow%3Ares2df)
|
|
46
56
|
[](https://codecov.io/gh/equinor/res2df)
|
|
47
|
-
[](https://www.python.org)
|
|
48
58
|
[](https://github.com/astral-sh/ruff)
|
|
49
59
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
50
60
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[](https://github.com/equinor/res2df/actions?query=workflow%3Ares2df)
|
|
2
2
|
[](https://codecov.io/gh/equinor/res2df)
|
|
3
|
-
[](https://www.python.org)
|
|
4
4
|
[](https://github.com/astral-sh/ruff)
|
|
5
5
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
6
6
|
|
|
@@ -10,6 +10,7 @@ import re
|
|
|
10
10
|
import shlex
|
|
11
11
|
import signal
|
|
12
12
|
import sys
|
|
13
|
+
from collections import defaultdict
|
|
13
14
|
from pathlib import Path
|
|
14
15
|
from typing import Any, Dict, List, Optional, Set, Union
|
|
15
16
|
|
|
@@ -397,7 +398,7 @@ def merge_zones(
|
|
|
397
398
|
zone_df.index.name = "K"
|
|
398
399
|
zone_df.reset_index(inplace=True)
|
|
399
400
|
|
|
400
|
-
df[zoneheader] = df[kname].map(zonedict)
|
|
401
|
+
df[zoneheader] = df[kname].map(defaultdict(lambda: None, zonedict))
|
|
401
402
|
return df
|
|
402
403
|
|
|
403
404
|
|
|
@@ -476,7 +477,7 @@ def fill_reverse_parser(
|
|
|
476
477
|
"""
|
|
477
478
|
parser.add_argument(
|
|
478
479
|
"csvfile",
|
|
479
|
-
help="Name of CSV file with " + modulename + " data with
|
|
480
|
+
help="Name of CSV file with " + modulename + " data with res2df format",
|
|
480
481
|
)
|
|
481
482
|
parser.add_argument(
|
|
482
483
|
"-o",
|
|
@@ -690,7 +691,7 @@ def generic_deck_table(
|
|
|
690
691
|
|
|
691
692
|
# NaN or Nones are assumed to be defaulted, which in Eclipse terminology is
|
|
692
693
|
# the string "1*":
|
|
693
|
-
dframe.fillna(value="1*"
|
|
694
|
+
dframe = dframe.fillna(value="1*")
|
|
694
695
|
|
|
695
696
|
if drop_trailing_columns:
|
|
696
697
|
for col_name in reversed(relevant_columns):
|
|
@@ -709,9 +710,9 @@ def generic_deck_table(
|
|
|
709
710
|
}
|
|
710
711
|
for int_col in integer_cols.intersection(dframe.columns):
|
|
711
712
|
defaulted_rows = dframe[int_col] == "1*"
|
|
712
|
-
dframe.loc[~defaulted_rows, int_col]
|
|
713
|
-
|
|
714
|
-
|
|
713
|
+
integer_values = dframe.loc[~defaulted_rows, int_col].astype(int)
|
|
714
|
+
dframe[int_col] = dframe[int_col].astype(str)
|
|
715
|
+
dframe.loc[~defaulted_rows, int_col] = integer_values
|
|
715
716
|
|
|
716
717
|
# Quote all string data. This is not always needed, but needed
|
|
717
718
|
# for some colums, for example well-names containing a slash.
|
|
@@ -826,9 +827,9 @@ def stack_on_colnames(
|
|
|
826
827
|
dframe.columns = pd.MultiIndex.from_tuples(
|
|
827
828
|
tuplecolumns, names=["dummy", stackcolname]
|
|
828
829
|
)
|
|
829
|
-
dframe = dframe.stack()
|
|
830
|
+
dframe = dframe.stack(future_stack=True)
|
|
830
831
|
staticcols = [col[0] for col in tuplecolumns if len(col) == 1]
|
|
831
|
-
dframe[staticcols] = dframe[staticcols].
|
|
832
|
+
dframe[staticcols] = dframe[staticcols].ffill()
|
|
832
833
|
dframe.reset_index(inplace=True)
|
|
833
834
|
# Drop rows stemming from the NaNs in the second tuple-element for
|
|
834
835
|
# static columns:
|
|
@@ -615,8 +615,7 @@ def expand_wlist(wlist_df: pd.DataFrame) -> pd.DataFrame:
|
|
|
615
615
|
and wlist_record["NAME"] not in currentstate
|
|
616
616
|
):
|
|
617
617
|
raise ValueError(
|
|
618
|
-
"WLIST ADD/DEL only works on existing well lists: "
|
|
619
|
-
f"{str(wlist_record)}"
|
|
618
|
+
f"WLIST ADD/DEL only works on existing well lists: {str(wlist_record)}"
|
|
620
619
|
)
|
|
621
620
|
if wlist_record["ACTION"] == "ADD":
|
|
622
621
|
currentstate[wlist_record["NAME"]] = " ".join(
|
|
@@ -888,14 +887,12 @@ def applywelopen(
|
|
|
888
887
|
].drop_duplicates(subset=["I", "J", "K1", "K2"], keep="last")
|
|
889
888
|
else:
|
|
890
889
|
raise ValueError(
|
|
891
|
-
"A WELOPEN keyword contains data that could not be parsed. "
|
|
892
|
-
f"\n {row} "
|
|
890
|
+
f"A WELOPEN keyword contains data that could not be parsed. \n {row} "
|
|
893
891
|
)
|
|
894
892
|
|
|
895
893
|
if previous_state.empty:
|
|
896
894
|
raise ValueError(
|
|
897
|
-
"A WELOPEN keyword is not acting on any existing connection. "
|
|
898
|
-
f"\n {row} "
|
|
895
|
+
f"A WELOPEN keyword is not acting on any existing connection. \n {row} "
|
|
899
896
|
)
|
|
900
897
|
|
|
901
898
|
new_state = previous_state
|
|
@@ -90,8 +90,7 @@ def get_parser() -> argparse.ArgumentParser:
|
|
|
90
90
|
"satfunc",
|
|
91
91
|
help="Write saturation function include files",
|
|
92
92
|
description=(
|
|
93
|
-
"Write saturation function include files from CSV files with "
|
|
94
|
-
"res2df format."
|
|
93
|
+
"Write saturation function include files from CSV files with res2df format."
|
|
95
94
|
),
|
|
96
95
|
)
|
|
97
96
|
satfunc_fill_reverse_parser(satfunc_parser)
|
|
@@ -298,7 +298,7 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
|
|
|
298
298
|
"-o",
|
|
299
299
|
"--output",
|
|
300
300
|
type=str,
|
|
301
|
-
help=("Name of output csv file.
|
|
301
|
+
help=("Name of output csv file. Use '-' for stdout."),
|
|
302
302
|
default="equil.csv",
|
|
303
303
|
)
|
|
304
304
|
parser.add_argument(
|
|
@@ -686,10 +686,7 @@ def df2res(
|
|
|
686
686
|
|
|
687
687
|
if "GLOBAL_INDEX" not in grid_df:
|
|
688
688
|
logger.warning(
|
|
689
|
-
(
|
|
690
|
-
"Global index not found in grid dataframe. "
|
|
691
|
-
"Assumes all cells are active"
|
|
692
|
-
)
|
|
689
|
+
("Global index not found in grid dataframe. Assumes all cells are active")
|
|
693
690
|
)
|
|
694
691
|
# Drop NaN rows for columns to be used (triggered by stacked
|
|
695
692
|
# dates and no global index, unlikely)
|
|
@@ -9,6 +9,7 @@ import sys
|
|
|
9
9
|
import warnings
|
|
10
10
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
11
11
|
|
|
12
|
+
import numpy as np
|
|
12
13
|
import pandas as pd
|
|
13
14
|
import treelib
|
|
14
15
|
|
|
@@ -19,6 +20,7 @@ with contextlib.suppress(ImportError):
|
|
|
19
20
|
import opm.io
|
|
20
21
|
|
|
21
22
|
from .common import (
|
|
23
|
+
OPMKEYWORDS,
|
|
22
24
|
parse_opmio_date_rec,
|
|
23
25
|
parse_opmio_deckrecord,
|
|
24
26
|
parse_opmio_tstep_rec,
|
|
@@ -91,7 +93,7 @@ def df(
|
|
|
91
93
|
# Flags which will tell when a new network related keyword
|
|
92
94
|
# has been encountered
|
|
93
95
|
keywords = ["GRUPTREE", "BRANPROP", "WELSPECS", "GRUPNET", "NODEPROP"]
|
|
94
|
-
found_keywords =
|
|
96
|
+
found_keywords = dict.fromkeys(keywords, False)
|
|
95
97
|
for kword in deck:
|
|
96
98
|
if kword.name in ["DATES", "START", "TSTEP"]:
|
|
97
99
|
# Whenever we encounter a new DATES, it means that
|
|
@@ -107,7 +109,7 @@ def df(
|
|
|
107
109
|
edgerecords += _write_edgerecords(
|
|
108
110
|
currentedges, nodedata, wellspecsedges, found_keywords, date
|
|
109
111
|
)
|
|
110
|
-
found_keywords =
|
|
112
|
+
found_keywords = dict.fromkeys(keywords, False)
|
|
111
113
|
# Done dumping the data for the previous date, parse the fresh
|
|
112
114
|
# date:
|
|
113
115
|
if kword.name in ["DATES", "START"]:
|
|
@@ -164,6 +166,17 @@ def df(
|
|
|
164
166
|
currentedges, nodedata, wellspecsedges, found_keywords, date
|
|
165
167
|
)
|
|
166
168
|
dframe = pd.DataFrame(edgerecords)
|
|
169
|
+
|
|
170
|
+
string_cols = {"PARENT", "CHILD"}
|
|
171
|
+
for keyword in ["GRUPTREE", "BRANPROP", "NODEPROP", "GRUPNET", "WELSPECS"]:
|
|
172
|
+
string_cols |= {
|
|
173
|
+
item["name"]
|
|
174
|
+
for item in OPMKEYWORDS[keyword]["items"]
|
|
175
|
+
if item["value_type"] == "STRING"
|
|
176
|
+
}
|
|
177
|
+
for col in string_cols:
|
|
178
|
+
if col in dframe:
|
|
179
|
+
dframe[col] = dframe[col].replace(np.nan, None)
|
|
167
180
|
if "DATE" in dframe:
|
|
168
181
|
dframe["DATE"] = pd.to_datetime(dframe["DATE"])
|
|
169
182
|
|
|
@@ -90,8 +90,8 @@ def _rftrecords2df(rftfile: ResdataFile) -> pd.DataFrame:
|
|
|
90
90
|
nav_df.loc[nav_df["recordname"] == "TIME", "timeindex"] = nav_df[
|
|
91
91
|
nav_df["recordname"] == "TIME"
|
|
92
92
|
].index
|
|
93
|
-
nav_df.
|
|
94
|
-
|
|
93
|
+
nav_df.ffill(
|
|
94
|
+
inplace=True
|
|
95
95
|
) # forward fill (because any record is associated to the previous TIME record)
|
|
96
96
|
nav_df["timeindex"] = nav_df["timeindex"].astype(int)
|
|
97
97
|
logger.info(
|
|
@@ -242,7 +242,7 @@ def process_seg_topology(seg_data: pd.DataFrame) -> pd.DataFrame:
|
|
|
242
242
|
seg_data = seg_data.sort_values("SEGIDX")
|
|
243
243
|
# For the first segment, None is allowed as SEGNXT, which excludes
|
|
244
244
|
# int as a Pandas type. Convert to 0 for the moment
|
|
245
|
-
seg_data["SEGNXT"] = seg_data["SEGNXT"].fillna(value=0).astype(int)
|
|
245
|
+
seg_data["SEGNXT"] = seg_data["SEGNXT"].fillna(value="0").astype(int)
|
|
246
246
|
|
|
247
247
|
# Outer merge first to add the upstream segment information to every row.
|
|
248
248
|
merged = pd.merge(
|
|
@@ -481,14 +481,14 @@ def add_extras(dframe: pd.DataFrame, inplace: bool = True) -> pd.DataFrame:
|
|
|
481
481
|
dframe = dframe.copy()
|
|
482
482
|
|
|
483
483
|
if "CONPRES" in dframe and "SEGPRES" in dframe:
|
|
484
|
-
dframe["COMPLETION_DP"] = 0
|
|
484
|
+
dframe["COMPLETION_DP"] = 0.0
|
|
485
485
|
nonzero_pres = (dframe["CONPRES"] > 0) & (dframe["SEGPRES"] > 0)
|
|
486
486
|
dframe.loc[nonzero_pres, "COMPLETION_DP"] = (
|
|
487
487
|
dframe.loc[nonzero_pres, "CONPRES"] - dframe.loc[nonzero_pres, "SEGPRES"]
|
|
488
488
|
)
|
|
489
489
|
|
|
490
490
|
if not dframe.empty:
|
|
491
|
-
dframe["DRAWDOWN"] = 0 # Set a default so that the column always exists
|
|
491
|
+
dframe["DRAWDOWN"] = 0.0 # Set a default so that the column always exists
|
|
492
492
|
|
|
493
493
|
if "CONPRES" in dframe and "PRESSURE" in dframe:
|
|
494
494
|
nonzero_conpres = dframe["CONPRES"] > 0
|
|
@@ -144,9 +144,9 @@ def interpolate_defaults(dframe: pd.DataFrame) -> pd.DataFrame:
|
|
|
144
144
|
can consist of multiple SATNUMs.
|
|
145
145
|
"""
|
|
146
146
|
sat_cols: set = {"SW", "SO", "SG", "SL"}.intersection(dframe.columns)
|
|
147
|
-
assert (
|
|
148
|
-
|
|
149
|
-
)
|
|
147
|
+
assert len(sat_cols) == 1, (
|
|
148
|
+
f"Could not determine a single saturation column in {dframe.columns}"
|
|
149
|
+
)
|
|
150
150
|
sat_col = list(sat_cols)[0]
|
|
151
151
|
|
|
152
152
|
if dframe[sat_col].isna().any():
|
|
@@ -154,11 +154,12 @@ def interpolate_defaults(dframe: pd.DataFrame) -> pd.DataFrame:
|
|
|
154
154
|
|
|
155
155
|
filled_frames = []
|
|
156
156
|
for _, subframe in dframe.groupby("SATNUM"):
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
subframe.set_index(sat_col, inplace=True)
|
|
158
|
+
numeric_columns = subframe.select_dtypes(include=["float", "int"]).columns
|
|
159
|
+
subframe[numeric_columns] = subframe[numeric_columns].interpolate(
|
|
160
|
+
method="index", limit_area="inside"
|
|
161
161
|
)
|
|
162
|
+
filled_frames.append(subframe.reset_index())
|
|
162
163
|
return pd.concat(filled_frames)
|
|
163
164
|
|
|
164
165
|
|
|
@@ -461,7 +461,9 @@ def _ensure_unique_datetime_index(dframe: pd.DataFrame) -> pd.DataFrame:
|
|
|
461
461
|
|
|
462
462
|
if dframe.attrs["meta"]["TIMESTEP"]["unit"] == "DAYS":
|
|
463
463
|
for idx in np.where(index_duplicates)[0]:
|
|
464
|
-
index_as_list[idx] += dt.timedelta(
|
|
464
|
+
index_as_list[idx] += dt.timedelta(
|
|
465
|
+
days=dframe["TIMESTEP"].iloc[idx]
|
|
466
|
+
)
|
|
465
467
|
elif dframe.attrs["meta"]["TIMESTEP"]["unit"] == "HOURS":
|
|
466
468
|
for idx in np.where(index_duplicates)[0]:
|
|
467
469
|
index_as_list[idx] += dt.timedelta(hours=dframe["TIMESTEP"][idx])
|
|
@@ -761,9 +763,7 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
|
|
|
761
763
|
"-o",
|
|
762
764
|
"--output",
|
|
763
765
|
type=str,
|
|
764
|
-
help=(
|
|
765
|
-
"Name of output file. Use '-' to write to stdout. " "Default 'summary.csv'"
|
|
766
|
-
),
|
|
766
|
+
help=("Name of output file. Use '-' to write to stdout. Default 'summary.csv'"),
|
|
767
767
|
default="summary.csv",
|
|
768
768
|
)
|
|
769
769
|
parser.add_argument("--arrow", action="store_true", help="Write to pyarrow format")
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: res2df
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Convert reservoir simulator input and output to DataFrames
|
|
5
5
|
Home-page: http://github.com/equinor/res2df
|
|
6
6
|
Author: Håvard Berland
|
|
7
7
|
Author-email: havb@equinor.com
|
|
8
8
|
License: GPLv3
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Requires-Dist: resdata>=5.0.0-b0
|
|
@@ -41,10 +41,20 @@ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
|
|
|
41
41
|
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
42
42
|
Provides-Extra: ert
|
|
43
43
|
Requires-Dist: ert>=10.2.0b13; extra == "ert"
|
|
44
|
+
Dynamic: author
|
|
45
|
+
Dynamic: author-email
|
|
46
|
+
Dynamic: description
|
|
47
|
+
Dynamic: description-content-type
|
|
48
|
+
Dynamic: home-page
|
|
49
|
+
Dynamic: license
|
|
50
|
+
Dynamic: provides-extra
|
|
51
|
+
Dynamic: requires-dist
|
|
52
|
+
Dynamic: requires-python
|
|
53
|
+
Dynamic: summary
|
|
44
54
|
|
|
45
55
|
[](https://github.com/equinor/res2df/actions?query=workflow%3Ares2df)
|
|
46
56
|
[](https://codecov.io/gh/equinor/res2df)
|
|
47
|
-
[](https://www.python.org)
|
|
48
58
|
[](https://github.com/astral-sh/ruff)
|
|
49
59
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
50
60
|
|
|
@@ -446,7 +446,7 @@ RSVD
|
|
|
446
446
|
pd.testing.assert_frame_equal(rsvd_df, rsvd_df_fromcsv)
|
|
447
447
|
|
|
448
448
|
|
|
449
|
-
def
|
|
449
|
+
def test_ntequl_no_eqldims():
|
|
450
450
|
"""Test that we can infer NTEQUL when not supplied"""
|
|
451
451
|
deckstr = """
|
|
452
452
|
GAS
|
|
@@ -479,6 +479,8 @@ EQUIL
|
|
|
479
479
|
with pytest.raises((ValueError, RuntimeError)):
|
|
480
480
|
equil.df(deckstr, ntequl=3)
|
|
481
481
|
|
|
482
|
+
|
|
483
|
+
def test_ntequl_with_eqldims():
|
|
482
484
|
deckstr = """
|
|
483
485
|
GAS
|
|
484
486
|
OIL
|
|
@@ -31,7 +31,7 @@ def test_eightcells_dataset():
|
|
|
31
31
|
|
|
32
32
|
expected_dframe = pd.DataFrame(
|
|
33
33
|
[
|
|
34
|
-
["2000-01-01", "FIELD", "GRUPTREE",
|
|
34
|
+
["2000-01-01", "FIELD", "GRUPTREE", None],
|
|
35
35
|
["2000-01-01", "OP1", "WELSPECS", "OPS"],
|
|
36
36
|
["2000-01-01", "OPS", "GRUPTREE", "FIELD"],
|
|
37
37
|
],
|
|
@@ -291,7 +291,7 @@ GRUPNET
|
|
|
291
291
|
{"CHILD": "FIELDB", "PARENT": None, "TERMINAL_PRESSURE": 80},
|
|
292
292
|
{"CHILD": "FIELDA", "PARENT": None, "TERMINAL_PRESSURE": 90},
|
|
293
293
|
{"CHILD": "OP", "PARENT": "FIELDA", "TERMINAL_PRESSURE": 100},
|
|
294
|
-
{"CHILD": "OPX", "PARENT": "FIELDB", "TERMINAL_PRESSURE":
|
|
294
|
+
{"CHILD": "OPX", "PARENT": "FIELDB", "TERMINAL_PRESSURE": np.nan},
|
|
295
295
|
]
|
|
296
296
|
),
|
|
297
297
|
"""
|
|
@@ -588,12 +588,12 @@ BRANPROP
|
|
|
588
588
|
""",
|
|
589
589
|
pd.DataFrame(
|
|
590
590
|
[
|
|
591
|
-
["2000-01-01", "FIELD", "GRUPTREE",
|
|
591
|
+
["2000-01-01", "FIELD", "GRUPTREE", None, np.nan, np.nan],
|
|
592
592
|
["2000-01-01", "TMPL_A", "GRUPTREE", "FIELD", np.nan, np.nan],
|
|
593
|
-
["2000-01-01", "FIELD", "BRANPROP",
|
|
593
|
+
["2000-01-01", "FIELD", "BRANPROP", None, np.nan, 20],
|
|
594
594
|
["2000-01-01", "NODE_A", "BRANPROP", "FIELD", 1, np.nan],
|
|
595
595
|
["2000-01-01", "TMPL_A", "BRANPROP", "NODE_A", 2, np.nan],
|
|
596
|
-
["2000-02-01", "FIELD", "BRANPROP",
|
|
596
|
+
["2000-02-01", "FIELD", "BRANPROP", None, np.nan, 20],
|
|
597
597
|
["2000-02-01", "NODE_A", "BRANPROP", "FIELD", 1, np.nan],
|
|
598
598
|
["2000-02-01", "NODE_B", "BRANPROP", "FIELD", 3, np.nan],
|
|
599
599
|
["2000-02-01", "TMPL_A", "BRANPROP", "NODE_B", 4, np.nan],
|
|
@@ -636,13 +636,13 @@ NODEPROP
|
|
|
636
636
|
""",
|
|
637
637
|
pd.DataFrame(
|
|
638
638
|
[
|
|
639
|
-
["2000-01-01", "FIELD", "GRUPTREE",
|
|
640
|
-
["2000-01-01", "TMPL_A", "GRUPTREE", "FIELD",
|
|
641
|
-
["2000-01-01", "FIELD", "BRANPROP",
|
|
642
|
-
["2000-01-01", "NODE_A", "BRANPROP", "FIELD", np.nan,
|
|
639
|
+
["2000-01-01", "FIELD", "GRUPTREE", None, np.nan, None],
|
|
640
|
+
["2000-01-01", "TMPL_A", "GRUPTREE", "FIELD", None, None],
|
|
641
|
+
["2000-01-01", "FIELD", "BRANPROP", None, 20, "NO"],
|
|
642
|
+
["2000-01-01", "NODE_A", "BRANPROP", "FIELD", np.nan, None],
|
|
643
643
|
["2000-01-01", "TMPL_A", "BRANPROP", "NODE_A", np.nan, "YES"],
|
|
644
|
-
["2000-02-01", "FIELD", "BRANPROP",
|
|
645
|
-
["2000-02-01", "NODE_A", "BRANPROP", "FIELD", np.nan,
|
|
644
|
+
["2000-02-01", "FIELD", "BRANPROP", None, 22, "YES"],
|
|
645
|
+
["2000-02-01", "NODE_A", "BRANPROP", "FIELD", np.nan, None],
|
|
646
646
|
["2000-02-01", "TMPL_A", "BRANPROP", "NODE_A", np.nan, "YES"],
|
|
647
647
|
],
|
|
648
648
|
columns=[
|
|
@@ -699,15 +699,15 @@ NODEPROP
|
|
|
699
699
|
# where there are two trees
|
|
700
700
|
pd.DataFrame(
|
|
701
701
|
[
|
|
702
|
-
["2000-01-01", "FIELD", "GRUPTREE",
|
|
702
|
+
["2000-01-01", "FIELD", "GRUPTREE", None],
|
|
703
703
|
["2000-01-01", "TMPL_A", "GRUPTREE", "FIELD"],
|
|
704
704
|
["2000-01-01", "WELL_2", "WELSPECS", "TMPL_B"],
|
|
705
705
|
["2000-01-01", "TMPL_B", "GRUPTREE", "FIELD"],
|
|
706
|
-
["2000-01-01", "FIELD", "BRANPROP",
|
|
706
|
+
["2000-01-01", "FIELD", "BRANPROP", None],
|
|
707
707
|
["2000-01-01", "NODE_A", "BRANPROP", "FIELD"],
|
|
708
708
|
["2000-01-01", "TMPL_A", "BRANPROP", "NODE_A"],
|
|
709
709
|
["2000-01-01", "WELL_1", "WELSPECS", "TMPL_A"],
|
|
710
|
-
["2000-02-01", "FIELD", "BRANPROP",
|
|
710
|
+
["2000-02-01", "FIELD", "BRANPROP", None],
|
|
711
711
|
["2000-02-01", "NODE_A", "BRANPROP", "FIELD"],
|
|
712
712
|
["2000-02-01", "TMPL_A", "BRANPROP", "NODE_A"],
|
|
713
713
|
["2000-02-01", "WELL_1", "WELSPECS", "TMPL_A"],
|