res2df 1.3.10__tar.gz → 1.3.12__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.3.10 → res2df-1.3.12}/.github/workflows/res2df.yml +30 -20
- {res2df-1.3.10 → res2df-1.3.12}/.github/workflows/style.yml +1 -1
- {res2df-1.3.10 → res2df-1.3.12}/.github/workflows/typing.yml +1 -1
- {res2df-1.3.10 → res2df-1.3.12}/.pre-commit-config.yaml +1 -1
- {res2df-1.3.10 → res2df-1.3.12}/PKG-INFO +6 -5
- {res2df-1.3.10 → res2df-1.3.12}/README.md +1 -1
- {res2df-1.3.10 → res2df-1.3.12}/pyproject.toml +37 -11
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/common.py +20 -20
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/compdat.py +3 -3
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/faults.py +9 -5
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/fipreports.py +2 -1
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/grid.py +10 -13
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/gruptree.py +10 -10
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/inferdims.py +2 -2
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/nnc.py +2 -6
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/parameters.py +5 -4
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/pillars.py +1 -1
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/pvt.py +1 -1
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/satfunc.py +8 -9
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/summary.py +8 -7
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/trans.py +4 -4
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/version.py +3 -3
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/vfp/_vfp.py +2 -2
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/vfp/_vfpcommon.py +7 -11
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/vfp/_vfpinj.py +12 -15
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/vfp/_vfpprod.py +9 -12
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/wellcompletiondata.py +1 -1
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/wellconnstatus.py +1 -1
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df.egg-info/PKG-INFO +6 -5
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df.egg-info/requires.txt +3 -3
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_common.py +1 -8
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_equil.py +1 -1
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_gruptree.py +9 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_summary.py +24 -8
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_summary_restarts.py +1 -1
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_trans.py +2 -2
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_vfp.py +9 -9
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_welopen.py +50 -0
- {res2df-1.3.10 → res2df-1.3.12}/.github/dependabot.yml +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/.github/workflows/codecov.yml +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/.github/workflows/publish.yml +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/.gitignore +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/CONTRIBUTING.md +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/LICENSE +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/SECURITY.md +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/ci/testkomodo.sh +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/_static/equinor-logo.png +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/_static/equinor-logo2.jpg +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/_static/equinor_logo.jpg +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/_static/equinor_logo_only.jpg +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/_templates/layout.html +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/conf.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/contribution.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/csv2res.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/glossary.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/history.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/index.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/installation.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/introduction.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/res2csv.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/compdat.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/compdat.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/equil-example.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/equil.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/fipnum.inc +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/fipreports-example.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/fipreports-example.txt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/fipreports.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/grid.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/grid.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/gruptree.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/gruptree.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/gruptreenet.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/images/injectoranalysis.png +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/images/multibranch-rftanalysis.png +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/nnc.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/nnc.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/outflow.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/pillars-dyn1-stacked.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/pillars-dyn1-unstacked.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/pillars-example1.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/pillars.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/pvt.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/pvt.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/rft.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/rft_columns.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/satfunc.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/satfunc.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/summary.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/summary.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/trans-boundaries.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/trans-group.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/trans.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/trans1.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/wcon.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/wcon.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/well_connection_status.csv +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage/wellconnstatus.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/docs/usage.rst +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/setup.cfg +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/__init__.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/__version__.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/constants.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/csv2res.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/equil.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/hook_implementations/__init__.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/hook_implementations/forward_model_steps.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/BRANPROP +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/COMPDAT +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/COMPLUMP +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/COMPSEGS +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/DENSITY +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/EQLDIMS +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/EQUIL +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/FAULTS +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/GRUPNET +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/GRUPTREE +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/NODEPROP +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/PBVD +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/PDVD +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/PVDG +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/PVDO +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/PVTG +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/PVTO +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/PVTW +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/ROCK +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/RSVD +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/RVVD +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/SGFN +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/SGOF +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/SGWFN +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/SLGOF +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/SOF2 +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/SOF3 +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/SWFN +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/SWOF +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/TABDIMS +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/VFPINJ +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/VFPPROD +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WCONHIST +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WCONINJE +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WCONINJH +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WCONPROD +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WELOPEN +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WELSEGS +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WELSPECS +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WLIST +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WSEGAICD +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WSEGSICD +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/WSEGVALV +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/__init__.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/readme +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/opmkeywords/runmetoupdate.sh +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/py.typed +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/res2csv.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/res2csvlogger.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/resdatafiles.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/rft.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/svg_color_keyword_names.txt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/vfp/__init__.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/vfp/_vfpdefs.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df/wcon.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df.egg-info/SOURCES.txt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df.egg-info/dependency_links.txt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df.egg-info/entry_points.txt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df.egg-info/not-zip-safe +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/src/res2df.egg-info/top_level.txt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/__init__.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/conftest.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/EIGHTCELLS.DATA +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/EIGHTCELLS.EGRID +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/EIGHTCELLS.INIT +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/EIGHTCELLS.INSPEC +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/EIGHTCELLS.PRT +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/EIGHTCELLS.RFT +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/EIGHTCELLS.RSSPEC +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/EIGHTCELLS.SMSPEC +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/EIGHTCELLS.UNRST +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/EIGHTCELLS.UNSMRY +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/eightcells_duplicated_summary_vector/EIGHTCELLS_DUPES.DATA +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/eightcells_duplicated_summary_vector/EIGHTCELLS_DUPES.SMSPEC +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/eightcells_duplicated_summary_vector/EIGHTCELLS_DUPES.UNSMRY +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/eightcells/zones.lyr +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/fipreports/TEST1.PRT +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/grid/reek.faults +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/grid/reek.grid +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/grid/reek.multflt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/grid/reek.multz +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/grid/reek.perm +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/grid/reek.poro +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/props/let-sgof.txt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/props/let-swof.txt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/props/reek.endpoints +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/props/reek.pvt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/props/reek.swatinit +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/props/sgof.txt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/props/swof.inc +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/props/swof.txt +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/regions/reek.eqlnum +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/regions/reek.fipnum +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/schedule/op6_aicd1_gp.sch +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/schedule/op6_icd1_gp.sch +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/schedule/op6_valve1_gp.sch +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/schedule/reek_history.sch +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/solution/reek.equil +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/include/summary/reek.smry +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0-OPMFLOW.PRT +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0.DATA +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0.ECLEND +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0.EGRID +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0.INIT +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0.LOG +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0.PRT +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0.RFT +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0.SMSPEC +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0.UNRST +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/2_R001_REEK-0.UNSMRY +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/reek/eclipse/model/zones.lyr +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP.DATA +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP.SMSPEC +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP.UNSMRY +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP_LONG.DATA +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP_LONG.SMSPEC +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP_LONG.UNSMRY +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP.DATA +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP.SMSPEC +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP.UNSMRY +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP_LONG.DATA +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP_LONG.SMSPEC +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/data/timesteps/SHORT_STEP_WITH_TIMESTEP_LONG.UNSMRY +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_compdat.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_eclfiles.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_ert_hooks.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_faults.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_fipreports.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_grid.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_hook_implementations.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_inferdims.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_init.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_integration.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_logging.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_nnc.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_parameters.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_pillars.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_pvt.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_rft.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_satfunc.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_userapi.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_wcon.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_wellcompletiondata.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_wellconnstatus.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_wlist.py +0 -0
- {res2df-1.3.10 → res2df-1.3.12}/tests/test_zonemap.py +0 -0
|
@@ -10,7 +10,7 @@ on:
|
|
|
10
10
|
|
|
11
11
|
schedule:
|
|
12
12
|
# Run CI every night and check that tests are working with latest dependencies
|
|
13
|
-
- cron:
|
|
13
|
+
- cron: "0 0 * * *"
|
|
14
14
|
|
|
15
15
|
env:
|
|
16
16
|
ERT_SHOW_BACKTRACE: 1
|
|
@@ -21,16 +21,23 @@ jobs:
|
|
|
21
21
|
runs-on: ubuntu-latest
|
|
22
22
|
strategy:
|
|
23
23
|
matrix:
|
|
24
|
-
python-version: [
|
|
24
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
25
|
+
pandas-version: [""]
|
|
25
26
|
include:
|
|
26
27
|
# For one of the Python versions we
|
|
27
28
|
# install the extra dependency ert
|
|
28
29
|
# (in order to not double the job matrix)
|
|
29
|
-
- python-version:
|
|
30
|
+
- python-version: "3.11"
|
|
30
31
|
install-ert: true
|
|
32
|
+
- python-version: "3.13"
|
|
33
|
+
pandas-version: ">=2,<3"
|
|
34
|
+
- python-version: "3.13"
|
|
35
|
+
pandas-version: ">=3.0.0"
|
|
36
|
+
exclude:
|
|
37
|
+
- python-version: "3.13"
|
|
38
|
+
pandas-version: ""
|
|
31
39
|
|
|
32
40
|
steps:
|
|
33
|
-
|
|
34
41
|
- name: Install Ubuntu dependencies
|
|
35
42
|
run: |
|
|
36
43
|
sudo apt-get update
|
|
@@ -59,11 +66,14 @@ jobs:
|
|
|
59
66
|
run: |
|
|
60
67
|
uv pip install ".[tests, docs]"
|
|
61
68
|
|
|
62
|
-
|
|
63
69
|
- name: Install ert
|
|
64
70
|
if: matrix.install-ert
|
|
65
71
|
run: uv pip install ".[ert]"
|
|
66
72
|
|
|
73
|
+
- name: Pin pandas version
|
|
74
|
+
if: matrix.pandas-version
|
|
75
|
+
run: uv pip install "pandas${{ matrix.pandas-version }}"
|
|
76
|
+
|
|
67
77
|
- name: List all installed packages
|
|
68
78
|
run: uv pip freeze
|
|
69
79
|
|
|
@@ -84,22 +94,22 @@ jobs:
|
|
|
84
94
|
- name: Update GitHub pages
|
|
85
95
|
if: github.repository_owner == 'equinor' && github.ref == 'refs/heads/master' && matrix.python-version == '3.11'
|
|
86
96
|
run: |
|
|
87
|
-
|
|
97
|
+
cp -R ./build/sphinx/html ../html
|
|
88
98
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
99
|
+
git config --local user.email "res2df-github-action"
|
|
100
|
+
git config --local user.name "res2df-github-action"
|
|
101
|
+
git fetch origin gh-pages
|
|
102
|
+
git checkout --track origin/gh-pages
|
|
103
|
+
git clean -f -f -d -x
|
|
104
|
+
git rm -r *
|
|
95
105
|
|
|
96
|
-
|
|
106
|
+
cp -R ../html/* .
|
|
97
107
|
|
|
98
|
-
|
|
108
|
+
git add .
|
|
99
109
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
110
|
+
if git diff-index --quiet HEAD; then
|
|
111
|
+
echo "No changes in documentation. Skip documentation deploy."
|
|
112
|
+
else
|
|
113
|
+
git commit -m "Update Github Pages"
|
|
114
|
+
git push "https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" gh-pages
|
|
115
|
+
fi
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: res2df
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.12
|
|
4
4
|
Summary: Convert reservoir simulator input and output to DataFrames
|
|
5
5
|
Author-email: Håvard Berland <havb@equinor.com>
|
|
6
6
|
License-Expression: GPL-3.0-only
|
|
@@ -16,6 +16,7 @@ Classifier: Topic :: Utilities
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
20
|
Classifier: Natural Language :: English
|
|
20
21
|
Requires-Python: >=3.11
|
|
21
22
|
Description-Content-Type: text/markdown
|
|
@@ -25,7 +26,7 @@ Requires-Dist: resfo
|
|
|
25
26
|
Requires-Dist: networkx
|
|
26
27
|
Requires-Dist: numpy
|
|
27
28
|
Requires-Dist: opm>=2020.10.2
|
|
28
|
-
Requires-Dist: pandas
|
|
29
|
+
Requires-Dist: pandas>=2
|
|
29
30
|
Requires-Dist: pyarrow
|
|
30
31
|
Requires-Dist: pyyaml>=5.1
|
|
31
32
|
Requires-Dist: treelib
|
|
@@ -48,10 +49,10 @@ Requires-Dist: sphinx-autoapi; extra == "docs"
|
|
|
48
49
|
Requires-Dist: ipython; extra == "docs"
|
|
49
50
|
Requires-Dist: rstcheck; extra == "docs"
|
|
50
51
|
Requires-Dist: setuptools; extra == "docs"
|
|
51
|
-
Requires-Dist: sphinx; extra == "docs"
|
|
52
|
+
Requires-Dist: sphinx<9; extra == "docs"
|
|
52
53
|
Requires-Dist: sphinx-argparse; extra == "docs"
|
|
53
54
|
Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
|
|
54
|
-
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
55
|
+
Requires-Dist: sphinx_rtd_theme>=3.1.0.rc1; extra == "docs"
|
|
55
56
|
Provides-Extra: ert
|
|
56
57
|
Requires-Dist: ert>=10.2.0b13; extra == "ert"
|
|
57
58
|
Dynamic: license-file
|
|
@@ -59,7 +60,7 @@ Dynamic: license-file
|
|
|
59
60
|
[](https://github.com/equinor/res2df/actions/workflows/publish.yml)
|
|
60
61
|
[](https://pypi.org/project/res2df/)
|
|
61
62
|
[](https://codecov.io/gh/equinor/res2df)
|
|
62
|
-
[](https://www.python.org)
|
|
63
64
|
[](https://github.com/astral-sh/ruff)
|
|
64
65
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
65
66
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[](https://github.com/equinor/res2df/actions/workflows/publish.yml)
|
|
2
2
|
[](https://pypi.org/project/res2df/)
|
|
3
3
|
[](https://codecov.io/gh/equinor/res2df)
|
|
4
|
-
[](https://www.python.org)
|
|
5
5
|
[](https://github.com/astral-sh/ruff)
|
|
6
6
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
7
7
|
|
|
@@ -28,6 +28,7 @@ classifiers = [
|
|
|
28
28
|
"Programming Language :: Python :: 3.11",
|
|
29
29
|
"Programming Language :: Python :: 3.12",
|
|
30
30
|
"Programming Language :: Python :: 3.13",
|
|
31
|
+
"Programming Language :: Python :: 3.14",
|
|
31
32
|
"Natural Language :: English",
|
|
32
33
|
]
|
|
33
34
|
|
|
@@ -39,7 +40,7 @@ dependencies= [
|
|
|
39
40
|
"networkx",
|
|
40
41
|
"numpy",
|
|
41
42
|
"opm>=2020.10.2",
|
|
42
|
-
"pandas",
|
|
43
|
+
"pandas >= 2",
|
|
43
44
|
"pyarrow",
|
|
44
45
|
"pyyaml>=5.1",
|
|
45
46
|
"treelib",
|
|
@@ -66,10 +67,10 @@ docs = [
|
|
|
66
67
|
"ipython",
|
|
67
68
|
"rstcheck",
|
|
68
69
|
"setuptools",
|
|
69
|
-
"sphinx",
|
|
70
|
+
"sphinx < 9",
|
|
70
71
|
"sphinx-argparse",
|
|
71
72
|
"sphinx-autodoc-typehints",
|
|
72
|
-
"sphinx_rtd_theme"
|
|
73
|
+
"sphinx_rtd_theme >= 3.1.0.rc1",
|
|
73
74
|
]
|
|
74
75
|
ert = ["ert>=10.2.0b13"]
|
|
75
76
|
|
|
@@ -127,19 +128,44 @@ line-length = 88
|
|
|
127
128
|
|
|
128
129
|
[tool.ruff.lint]
|
|
129
130
|
select = [
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"
|
|
131
|
+
"AIR", # airflow
|
|
132
|
+
"ANN", # flake8-annotations
|
|
133
|
+
"ASYNC", # flake8-async
|
|
133
134
|
"B", # flake-8-bugbear
|
|
134
|
-
"
|
|
135
|
+
"C4", # flake8-comprehensions
|
|
136
|
+
"DJ", # django
|
|
137
|
+
"E", # pycodestyle
|
|
135
138
|
"F", # pyflakes
|
|
136
|
-
"
|
|
139
|
+
"FA", # future-annotations
|
|
140
|
+
"FAST", # fastapi
|
|
141
|
+
"FIX", # fixme
|
|
142
|
+
"FLY", # flynt
|
|
143
|
+
"FURB", # refurb
|
|
144
|
+
"I", # isort
|
|
145
|
+
"ICN", # flake8-import-conventions
|
|
146
|
+
"INT", # gettext
|
|
147
|
+
"ISC", # flake8-implicit-str-concat
|
|
137
148
|
"NPY", # numpy specific rules
|
|
138
|
-
"C4", # flake8-comprehensions
|
|
139
149
|
"PD", # pandas-vet
|
|
150
|
+
"PERF", # perflint
|
|
151
|
+
"PGH", # pygrep-hooks
|
|
152
|
+
"PIE", # flake8-pie
|
|
153
|
+
"PL", # pylint
|
|
154
|
+
"PLC", # pylint convention
|
|
155
|
+
"PLE", # pylint error
|
|
156
|
+
"PLR", # pylint refactor
|
|
157
|
+
"PLW", # pylint warning
|
|
158
|
+
"PTH", # flake8-use-pathlib
|
|
159
|
+
"PYI", # flake8-pyi
|
|
160
|
+
"Q", # quotes
|
|
161
|
+
"RSE", # raise
|
|
140
162
|
"RUF", # ruff specific rules
|
|
163
|
+
"SIM", # flake-8-simplify
|
|
164
|
+
"SLOT", # flake8-slots
|
|
165
|
+
"TD", # todos
|
|
141
166
|
"UP", # pyupgrade
|
|
142
|
-
"
|
|
167
|
+
"W", # pycodestyle
|
|
168
|
+
"YTT", # year 2020
|
|
143
169
|
]
|
|
144
170
|
preview = true
|
|
145
171
|
ignore = [
|
|
@@ -161,7 +187,7 @@ ignore = [
|
|
|
161
187
|
|
|
162
188
|
[tool.ruff.lint.extend-per-file-ignores]
|
|
163
189
|
"src/res2df/__init__.py" = ["PLC0414"]
|
|
164
|
-
"tests/*" = ["RUF005", "ANN"]
|
|
190
|
+
"tests/*" = ["RUF005", "ANN", "FURB113", "PERF"]
|
|
165
191
|
"docs/*" = ["ANN"]
|
|
166
192
|
|
|
167
193
|
[tool.ruff.lint.pylint]
|
|
@@ -653,7 +653,7 @@ def generic_deck_table(
|
|
|
653
653
|
|
|
654
654
|
# Start building the string we are to return:
|
|
655
655
|
string = keyword + "\n"
|
|
656
|
-
if comment
|
|
656
|
+
if comment:
|
|
657
657
|
string += "\n".join(["-- " + line for line in comment.splitlines()]) + "\n"
|
|
658
658
|
|
|
659
659
|
# Empty tables are ok with Eclipse (at least sometimes)
|
|
@@ -664,7 +664,7 @@ def generic_deck_table(
|
|
|
664
664
|
# Pandas make a pretty txt table:
|
|
665
665
|
dframe = dframe.copy()
|
|
666
666
|
|
|
667
|
-
# Column names are pr.
|
|
667
|
+
# Column names are pr. res2df standard, redo to opm.common in order to use
|
|
668
668
|
# sorting from that:
|
|
669
669
|
if renamer is not None:
|
|
670
670
|
inv_renamer = {value: key for key, value in renamer.items()}
|
|
@@ -696,11 +696,14 @@ def generic_deck_table(
|
|
|
696
696
|
dframe = dframe.fillna(value="1*")
|
|
697
697
|
|
|
698
698
|
if drop_trailing_columns:
|
|
699
|
+
columns_to_drop = []
|
|
699
700
|
for col_name in reversed(relevant_columns):
|
|
700
|
-
if
|
|
701
|
-
|
|
701
|
+
if (dframe[col_name] == "1*").all():
|
|
702
|
+
columns_to_drop.append(col_name)
|
|
702
703
|
else:
|
|
703
704
|
break
|
|
705
|
+
if columns_to_drop:
|
|
706
|
+
dframe = dframe.drop(columns=columns_to_drop)
|
|
704
707
|
|
|
705
708
|
# It is critical for opm.common, maybe also E100 to have integers printed
|
|
706
709
|
# as integers, for correct parsing. Ensure these are integer where the json
|
|
@@ -708,13 +711,15 @@ def generic_deck_table(
|
|
|
708
711
|
integer_cols = {
|
|
709
712
|
item["name"]
|
|
710
713
|
for item in OPMKEYWORDS[keyword]["items"]
|
|
711
|
-
if item["value_type"] == "INT"
|
|
714
|
+
if item["value_type"] == "INT"
|
|
712
715
|
}
|
|
713
716
|
for int_col in integer_cols.intersection(dframe.columns):
|
|
714
|
-
|
|
715
|
-
integer_values = dframe.loc[~defaulted_rows, int_col].astype(int)
|
|
717
|
+
mask = dframe[int_col] != "1*"
|
|
716
718
|
dframe[int_col] = dframe[int_col].astype(str)
|
|
717
|
-
|
|
719
|
+
if mask.any():
|
|
720
|
+
dframe.loc[mask, int_col] = (
|
|
721
|
+
dframe.loc[mask, int_col].astype(float).astype(int).astype(str)
|
|
722
|
+
)
|
|
718
723
|
|
|
719
724
|
# Quote all string data. This is not always needed, but needed
|
|
720
725
|
# for some colums, for example well-names containing a slash.
|
|
@@ -726,9 +731,8 @@ def generic_deck_table(
|
|
|
726
731
|
for str_col in string_cols.intersection(dframe.columns):
|
|
727
732
|
# Ensure 1* is not quoted.
|
|
728
733
|
non_defaulted_rows = dframe[str_col] != "1*"
|
|
729
|
-
dframe.loc[non_defaulted_rows, str_col].str.replace("'", "")
|
|
730
734
|
dframe.loc[non_defaulted_rows, str_col] = (
|
|
731
|
-
"'" + dframe.loc[non_defaulted_rows, str_col] + "'"
|
|
735
|
+
"'" + dframe.loc[non_defaulted_rows, str_col].str.replace("'", "") + "'"
|
|
732
736
|
)
|
|
733
737
|
|
|
734
738
|
# Now rename again to have prettier column names:
|
|
@@ -739,8 +743,7 @@ def generic_deck_table(
|
|
|
739
743
|
tablestring = dframe.to_string(header=True, index=False)
|
|
740
744
|
# Indent all lines with two spaces:
|
|
741
745
|
tablestring = "\n".join(
|
|
742
|
-
|
|
743
|
-
# The replace() in there is needed for py36/pandas==1.1.5 only.
|
|
746
|
+
" " + line.strip().replace(" /", " /") for line in tablestring.splitlines()
|
|
744
747
|
)
|
|
745
748
|
# Eclipse comment for the header line:
|
|
746
749
|
tablestring = "--" + tablestring[1:]
|
|
@@ -836,7 +839,7 @@ def stack_on_colnames(
|
|
|
836
839
|
# Drop rows stemming from the NaNs in the second tuple-element for
|
|
837
840
|
# static columns:
|
|
838
841
|
dframe = dframe.dropna(axis="index", subset=["DATE"])
|
|
839
|
-
|
|
842
|
+
dframe = dframe.drop(columns="level_0")
|
|
840
843
|
dframe.index.name = ""
|
|
841
844
|
return dframe
|
|
842
845
|
|
|
@@ -912,11 +915,11 @@ def parse_lyrfile(filename: str | Path) -> list[dict[str, Any]] | None:
|
|
|
912
915
|
zonedict["to_layer"] = to_layer
|
|
913
916
|
else:
|
|
914
917
|
logger.error("From_layer higher than to_layer")
|
|
915
|
-
raise ValueError
|
|
918
|
+
raise ValueError
|
|
916
919
|
elif len(numbers) == 1:
|
|
917
920
|
zonedict["span"] = int(numbers[0])
|
|
918
921
|
else:
|
|
919
|
-
raise ValueError
|
|
922
|
+
raise ValueError
|
|
920
923
|
lyrlist.append(zonedict)
|
|
921
924
|
except ValueError:
|
|
922
925
|
logger.error("Could not parse lyr file %s", filename)
|
|
@@ -967,14 +970,11 @@ def get_wells_matching_template(template: str, wells: list[str]) -> list[str]:
|
|
|
967
970
|
Returns:
|
|
968
971
|
List of matched wells
|
|
969
972
|
"""
|
|
970
|
-
if template.startswith("*"
|
|
973
|
+
if template.startswith(("*", "?")):
|
|
971
974
|
raise ValueError(
|
|
972
975
|
"Well template not allowed to start with a wildcard character: "
|
|
973
976
|
f"Must be preceded with a \\: {template}"
|
|
974
977
|
)
|
|
975
|
-
|
|
976
|
-
# Note that the two \\ are actually read as one and
|
|
977
|
-
# this will return True for f.ex '\*P1'
|
|
978
|
-
template = template[1:]
|
|
978
|
+
template = template.removeprefix("\\")
|
|
979
979
|
regex = template.replace("*", ".*").replace("?", ".")
|
|
980
980
|
return [well for well in wells if bool(re.match(regex, well))]
|
|
@@ -751,7 +751,7 @@ def expand_complump_in_welopen_df(
|
|
|
751
751
|
exp_welopens.append(cell_row)
|
|
752
752
|
|
|
753
753
|
dframe = pd.DataFrame(exp_welopens)
|
|
754
|
-
return dframe.astype(object).
|
|
754
|
+
return dframe.astype(object).replace({np.nan: None})
|
|
755
755
|
|
|
756
756
|
|
|
757
757
|
def expand_wlist_in_welopen_df(
|
|
@@ -785,7 +785,7 @@ def expand_wlist_in_welopen_df(
|
|
|
785
785
|
# Explicit wellname was used, no expansion to happen:
|
|
786
786
|
exp_welopens.append(row)
|
|
787
787
|
dframe = pd.DataFrame(exp_welopens)
|
|
788
|
-
return dframe.astype(object).
|
|
788
|
+
return dframe.astype(object).replace({np.nan: None})
|
|
789
789
|
|
|
790
790
|
|
|
791
791
|
def applywelopen(
|
|
@@ -844,7 +844,7 @@ def applywelopen(
|
|
|
844
844
|
"The WLIST dataframe must be expanded through expand_wlist()"
|
|
845
845
|
)
|
|
846
846
|
|
|
847
|
-
welopen_df = welopen_df.astype(object).
|
|
847
|
+
welopen_df = welopen_df.astype(object).replace({np.nan: None})
|
|
848
848
|
if wlist_df is not None:
|
|
849
849
|
welopen_df = expand_wlist_in_welopen_df(welopen_df, wlist_df)
|
|
850
850
|
if complump_df is not None:
|
|
@@ -7,6 +7,7 @@ a DataFrame
|
|
|
7
7
|
|
|
8
8
|
import argparse
|
|
9
9
|
import logging
|
|
10
|
+
from itertools import product
|
|
10
11
|
|
|
11
12
|
# Needed for mypy
|
|
12
13
|
import opm.io
|
|
@@ -36,7 +37,7 @@ def df(deck: "ResdataFiles | opm.opmcommon_python.Deck") -> pd.DataFrame:
|
|
|
36
37
|
|
|
37
38
|
# In[91]: list(deck['FAULTS'][0])
|
|
38
39
|
# Out[91]: [[u'F1'], [36], [36], [41], [42], [1], [14], [u'I']]
|
|
39
|
-
data = []
|
|
40
|
+
data: list[list[str | int]] = []
|
|
40
41
|
# It is allowed in Eclipse to use the keyword FAULTS
|
|
41
42
|
# as many times as needed. Thus we need to loop in some way:
|
|
42
43
|
for keyword in deck:
|
|
@@ -47,10 +48,13 @@ def df(deck: "ResdataFiles | opm.opmcommon_python.Deck") -> pd.DataFrame:
|
|
|
47
48
|
frec_dict = parse_opmio_deckrecord(rec, "FAULTS")
|
|
48
49
|
faultname = frec_dict["NAME"]
|
|
49
50
|
faultface = frec_dict["FACE"]
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
|
|
52
|
+
indices = product(
|
|
53
|
+
range(frec_dict["IX1"], frec_dict["IX2"] + 1),
|
|
54
|
+
range(frec_dict["IY1"], frec_dict["IY2"] + 1),
|
|
55
|
+
range(frec_dict["IZ1"], frec_dict["IZ2"] + 1),
|
|
56
|
+
)
|
|
57
|
+
data.extend([faultname, i, j, k, faultface] for i, j, k in indices)
|
|
54
58
|
dframe = pd.DataFrame(columns=COLUMNS, data=data)
|
|
55
59
|
logger.info("Extracted %i faults", len(dframe["NAME"].unique()))
|
|
56
60
|
return dframe
|
|
@@ -4,6 +4,7 @@ import argparse
|
|
|
4
4
|
import datetime
|
|
5
5
|
import logging
|
|
6
6
|
import re
|
|
7
|
+
from pathlib import Path
|
|
7
8
|
|
|
8
9
|
import numpy as np
|
|
9
10
|
import pandas as pd
|
|
@@ -133,7 +134,7 @@ def df(prtfile: str | ResdataFiles, fipname: str = "FIPNUM") -> pd.DataFrame:
|
|
|
133
134
|
".+" + fipname + r"\s+REPORT\s+REGION\s+(\d+)", re.IGNORECASE
|
|
134
135
|
)
|
|
135
136
|
|
|
136
|
-
with open(
|
|
137
|
+
with Path(prtfile).open(encoding="utf-8") as prt_fh:
|
|
137
138
|
logger.info(
|
|
138
139
|
"Parsing file %s for blocks starting with %s REPORT REGION",
|
|
139
140
|
prtfile,
|
|
@@ -47,7 +47,7 @@ def get_available_rst_dates(resdatafiles: ResdataFiles) -> list[datetime.date]:
|
|
|
47
47
|
)
|
|
48
48
|
return [
|
|
49
49
|
resdatafiles.get_rstfile().iget_restart_sim_time(index).date()
|
|
50
|
-
for index in range(
|
|
50
|
+
for index in range(len(report_indices))
|
|
51
51
|
]
|
|
52
52
|
|
|
53
53
|
|
|
@@ -544,7 +544,7 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
|
|
|
544
544
|
parser.add_argument(
|
|
545
545
|
"DATAFILE",
|
|
546
546
|
help="Name of the .DATA input file for the reservoir simulator."
|
|
547
|
-
|
|
547
|
+
" There must exist .INIT and .EGRID files with the same path and basename.",
|
|
548
548
|
)
|
|
549
549
|
parser.add_argument(
|
|
550
550
|
"--vectors",
|
|
@@ -556,8 +556,8 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
|
|
|
556
556
|
"--rstdates",
|
|
557
557
|
type=str,
|
|
558
558
|
help="Point in time to grab restart data from, "
|
|
559
|
-
|
|
560
|
-
|
|
559
|
+
"either 'first' or 'last', 'all', or a date in "
|
|
560
|
+
"YYYY-MM-DD format",
|
|
561
561
|
default="",
|
|
562
562
|
)
|
|
563
563
|
parser.add_argument(
|
|
@@ -610,10 +610,11 @@ def drop_constant_columns(
|
|
|
610
610
|
if dframe.empty:
|
|
611
611
|
return dframe
|
|
612
612
|
|
|
613
|
-
columnstodelete = [
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
613
|
+
columnstodelete = [
|
|
614
|
+
col
|
|
615
|
+
for col in (set(dframe.columns) - set(alwayskeep))
|
|
616
|
+
if len(dframe[col].unique()) == 1
|
|
617
|
+
]
|
|
617
618
|
if columnstodelete:
|
|
618
619
|
logging.info("Deleting constant columns %s", columnstodelete)
|
|
619
620
|
return dframe.drop(columnstodelete, axis=1)
|
|
@@ -698,11 +699,7 @@ def df2res(
|
|
|
698
699
|
|
|
699
700
|
res2df_header = (
|
|
700
701
|
"Output file printed by "
|
|
701
|
-
|
|
702
|
-
+ __version__
|
|
703
|
-
+ "\n"
|
|
704
|
-
+ " at "
|
|
705
|
-
+ str(datetime.datetime.now())
|
|
702
|
+
"res2df.grid " + __version__ + "\n" + " at " + str(datetime.datetime.now())
|
|
706
703
|
)
|
|
707
704
|
|
|
708
705
|
string = ""
|
|
@@ -9,9 +9,7 @@ import warnings
|
|
|
9
9
|
from typing import Any
|
|
10
10
|
|
|
11
11
|
import numpy as np
|
|
12
|
-
|
|
13
|
-
# Needed for mypy
|
|
14
|
-
import opm.io
|
|
12
|
+
import opm
|
|
15
13
|
import pandas as pd
|
|
16
14
|
import treelib
|
|
17
15
|
|
|
@@ -63,11 +61,14 @@ def df(
|
|
|
63
61
|
date: datetime.date | None
|
|
64
62
|
date = startdate if startdate is not None else None
|
|
65
63
|
|
|
64
|
+
if not isinstance(deck, (ResdataFiles, opm.opmcommon_python.Deck)):
|
|
65
|
+
raise TypeError("Input deck must be either ResdataFiles or an opm Deck.")
|
|
66
|
+
|
|
66
67
|
if isinstance(deck, ResdataFiles):
|
|
67
68
|
deck = deck.get_deck()
|
|
68
69
|
|
|
69
70
|
edgerecords = [] # list of dict of rows containing an edge.
|
|
70
|
-
nodedatarecords = []
|
|
71
|
+
nodedatarecords: list[dict[str, Any]] = []
|
|
71
72
|
|
|
72
73
|
# In order for the GRUPTREE/BRANPROP keywords to accumulate, we
|
|
73
74
|
# store the edges as dictionaries indexed by the edge
|
|
@@ -144,10 +145,10 @@ def df(
|
|
|
144
145
|
renamer = (
|
|
145
146
|
{"PRESSURE": "TERMINAL_PRESSURE"} if kword.name == "NODEPROP" else None
|
|
146
147
|
)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
nodedatarecords.extend(
|
|
149
|
+
parse_opmio_deckrecord(rec, kword.name, renamer=renamer)
|
|
150
|
+
for rec in kword
|
|
151
|
+
)
|
|
151
152
|
nodedata[kword.name] = (
|
|
152
153
|
pd.DataFrame(nodedatarecords)
|
|
153
154
|
.drop_duplicates(subset="NAME", keep="last")
|
|
@@ -178,7 +179,6 @@ def df(
|
|
|
178
179
|
# This happens with WELSPECS if both GRUPTREE and BRANPROP is defined
|
|
179
180
|
# at the same timestep. And when a node is redirected to a new parent node
|
|
180
181
|
dframe = dframe.drop_duplicates(subset=["DATE", "CHILD", "KEYWORD"], keep="last")
|
|
181
|
-
print(dframe)
|
|
182
182
|
return dframe
|
|
183
183
|
|
|
184
184
|
|
|
@@ -254,7 +254,7 @@ def _merge_edges_and_nodeinfo(
|
|
|
254
254
|
|
|
255
255
|
# Write WELSPECS edges
|
|
256
256
|
welspecs_parents = set()
|
|
257
|
-
for
|
|
257
|
+
for child, parent in wellspecsedges: # noqa: PLE1141
|
|
258
258
|
# For BRANPROP trees, only wells with a parent in the tree are added
|
|
259
259
|
if (treetype == "BRANPROP" and parent in childs) or (treetype == "GRUPTREE"):
|
|
260
260
|
rec_dict = {
|
|
@@ -38,7 +38,7 @@ def guess_dim(deckstring: str, dimkeyword: str, dimitem: int = 0) -> int:
|
|
|
38
38
|
raise ValueError("Only supports TABDIMS and EQLDIMS")
|
|
39
39
|
if dimkeyword == "TABDIMS" and dimitem not in [0, 1]:
|
|
40
40
|
raise ValueError("Only support item 0 and 1 in TABDIMS")
|
|
41
|
-
if dimkeyword == "EQLDIMS" and dimitem
|
|
41
|
+
if dimkeyword == "EQLDIMS" and dimitem != 0:
|
|
42
42
|
raise ValueError("Only item 0 in EQLDIMS can be estimated")
|
|
43
43
|
|
|
44
44
|
# A less than res2df-standard permissive opm.io, when using
|
|
@@ -112,7 +112,7 @@ def inject_dimcount(
|
|
|
112
112
|
raise ValueError("Only supports TABDIMS and EQLDIMS")
|
|
113
113
|
if dimkeyword == "TABDIMS" and dimitem not in [0, 1]:
|
|
114
114
|
raise ValueError("Only support item 0 and 1 in TABDIMS")
|
|
115
|
-
if dimkeyword == "EQLDIMS" and dimitem
|
|
115
|
+
if dimkeyword == "EQLDIMS" and dimitem != 0:
|
|
116
116
|
raise ValueError("Only item 0 in EQLDIMS can be injected")
|
|
117
117
|
|
|
118
118
|
if dimkeyword in deckstr:
|
|
@@ -181,7 +181,7 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
|
|
|
181
181
|
parser.add_argument(
|
|
182
182
|
"DATAFILE",
|
|
183
183
|
help="Name of the .DATA input file for the reservoir simulator."
|
|
184
|
-
|
|
184
|
+
" There must exist .INIT and .EGRID files with the same path and basename.",
|
|
185
185
|
)
|
|
186
186
|
parser.add_argument(
|
|
187
187
|
"-c",
|
|
@@ -242,11 +242,7 @@ def df2res_editnnc(
|
|
|
242
242
|
string = ""
|
|
243
243
|
res2df_header = (
|
|
244
244
|
"Output file printed by res2df.nnc"
|
|
245
|
-
+ " "
|
|
246
|
-
+ __version__
|
|
247
|
-
+ "\n"
|
|
248
|
-
+ " at "
|
|
249
|
-
+ str(datetime.datetime.now())
|
|
245
|
+
" " + __version__ + "\n" + " at " + str(datetime.datetime.now())
|
|
250
246
|
)
|
|
251
247
|
if not nocomments:
|
|
252
248
|
string += comment_formatter(res2df_header)
|
|
@@ -5,7 +5,7 @@ import json
|
|
|
5
5
|
import logging
|
|
6
6
|
import warnings
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import Any, cast
|
|
9
9
|
|
|
10
10
|
import pandas as pd
|
|
11
11
|
import yaml
|
|
@@ -47,7 +47,7 @@ def find_parameter_files(
|
|
|
47
47
|
filebase + ".txt",
|
|
48
48
|
filebase,
|
|
49
49
|
]
|
|
50
|
-
paths_to_check: list[Path] = [Path(
|
|
50
|
+
paths_to_check: list[Path] = [Path(), Path(".."), Path("..") / Path("..")]
|
|
51
51
|
foundfiles = []
|
|
52
52
|
for path in paths_to_check:
|
|
53
53
|
for fname in files_to_lookfor:
|
|
@@ -79,11 +79,12 @@ def load_parameterstxt(filename: str | Path) -> dict[str, Any]:
|
|
|
79
79
|
engine="python",
|
|
80
80
|
names=["KEY", "VALUE"],
|
|
81
81
|
index_col=False,
|
|
82
|
+
dtype={"KEY": str},
|
|
82
83
|
)
|
|
83
84
|
except pd.errors.ParserWarning as txt_exc:
|
|
84
85
|
raise pd.errors.ParserError(txt_exc) from txt_exc
|
|
85
86
|
|
|
86
|
-
return dframe.set_index("KEY")["VALUE"].to_dict()
|
|
87
|
+
return cast(dict[str, Any], dframe.set_index("KEY")["VALUE"].to_dict())
|
|
87
88
|
|
|
88
89
|
|
|
89
90
|
def load_all(
|
|
@@ -147,7 +148,7 @@ def load(filename: str | Path) -> dict[str, Any]:
|
|
|
147
148
|
if not params_dict:
|
|
148
149
|
try:
|
|
149
150
|
logger.debug("Trying to parse %s with json.load()", filename)
|
|
150
|
-
with open(
|
|
151
|
+
with Path(filename).open(encoding="utf-8") as f_handle:
|
|
151
152
|
params_dict = json.load(f_handle)
|
|
152
153
|
assert isinstance(params_dict, dict)
|
|
153
154
|
logger.debug(" - ok, parsed as yaml")
|