xtgeo 4.13.1__cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
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.
Potentially problematic release.
This version of xtgeo might be problematic. Click here for more details.
- cxtgeo.py +558 -0
- cxtgeoPYTHON_wrap.c +19537 -0
- xtgeo/__init__.py +246 -0
- xtgeo/_cxtgeo.cpython-313-aarch64-linux-gnu.so +0 -0
- xtgeo/_internal.cpython-313-aarch64-linux-gnu.so +0 -0
- xtgeo/common/__init__.py +19 -0
- xtgeo/common/_angles.py +29 -0
- xtgeo/common/_xyz_enum.py +50 -0
- xtgeo/common/calc.py +396 -0
- xtgeo/common/constants.py +30 -0
- xtgeo/common/exceptions.py +42 -0
- xtgeo/common/log.py +93 -0
- xtgeo/common/sys.py +166 -0
- xtgeo/common/types.py +18 -0
- xtgeo/common/version.py +34 -0
- xtgeo/common/xtgeo_dialog.py +604 -0
- xtgeo/cube/__init__.py +9 -0
- xtgeo/cube/_cube_export.py +214 -0
- xtgeo/cube/_cube_import.py +532 -0
- xtgeo/cube/_cube_roxapi.py +180 -0
- xtgeo/cube/_cube_utils.py +287 -0
- xtgeo/cube/_cube_window_attributes.py +273 -0
- xtgeo/cube/cube1.py +1023 -0
- xtgeo/grid3d/__init__.py +15 -0
- xtgeo/grid3d/_ecl_grid.py +774 -0
- xtgeo/grid3d/_ecl_inte_head.py +152 -0
- xtgeo/grid3d/_ecl_logi_head.py +71 -0
- xtgeo/grid3d/_ecl_output_file.py +81 -0
- xtgeo/grid3d/_egrid.py +1004 -0
- xtgeo/grid3d/_find_gridprop_in_eclrun.py +625 -0
- xtgeo/grid3d/_grdecl_format.py +309 -0
- xtgeo/grid3d/_grdecl_grid.py +400 -0
- xtgeo/grid3d/_grid3d.py +29 -0
- xtgeo/grid3d/_grid3d_fence.py +284 -0
- xtgeo/grid3d/_grid3d_utils.py +228 -0
- xtgeo/grid3d/_grid_boundary.py +76 -0
- xtgeo/grid3d/_grid_etc1.py +1595 -0
- xtgeo/grid3d/_grid_export.py +222 -0
- xtgeo/grid3d/_grid_hybrid.py +50 -0
- xtgeo/grid3d/_grid_import.py +79 -0
- xtgeo/grid3d/_grid_import_ecl.py +101 -0
- xtgeo/grid3d/_grid_import_roff.py +135 -0
- xtgeo/grid3d/_grid_import_xtgcpgeom.py +375 -0
- xtgeo/grid3d/_grid_refine.py +258 -0
- xtgeo/grid3d/_grid_roxapi.py +292 -0
- xtgeo/grid3d/_grid_translate_coords.py +154 -0
- xtgeo/grid3d/_grid_wellzone.py +165 -0
- xtgeo/grid3d/_gridprop_export.py +202 -0
- xtgeo/grid3d/_gridprop_import_eclrun.py +164 -0
- xtgeo/grid3d/_gridprop_import_grdecl.py +130 -0
- xtgeo/grid3d/_gridprop_import_roff.py +52 -0
- xtgeo/grid3d/_gridprop_import_xtgcpprop.py +168 -0
- xtgeo/grid3d/_gridprop_lowlevel.py +171 -0
- xtgeo/grid3d/_gridprop_op1.py +272 -0
- xtgeo/grid3d/_gridprop_roxapi.py +301 -0
- xtgeo/grid3d/_gridprop_value_init.py +140 -0
- xtgeo/grid3d/_gridprops_import_eclrun.py +344 -0
- xtgeo/grid3d/_gridprops_import_roff.py +83 -0
- xtgeo/grid3d/_roff_grid.py +470 -0
- xtgeo/grid3d/_roff_parameter.py +303 -0
- xtgeo/grid3d/grid.py +2957 -0
- xtgeo/grid3d/grid_properties.py +699 -0
- xtgeo/grid3d/grid_property.py +1313 -0
- xtgeo/grid3d/types.py +15 -0
- xtgeo/include/eigen3/Eigen/Cholesky +45 -0
- xtgeo/include/eigen3/Eigen/CholmodSupport +48 -0
- xtgeo/include/eigen3/Eigen/Core +384 -0
- xtgeo/include/eigen3/Eigen/Dense +7 -0
- xtgeo/include/eigen3/Eigen/Eigen +2 -0
- xtgeo/include/eigen3/Eigen/Eigenvalues +60 -0
- xtgeo/include/eigen3/Eigen/Geometry +59 -0
- xtgeo/include/eigen3/Eigen/Householder +29 -0
- xtgeo/include/eigen3/Eigen/IterativeLinearSolvers +48 -0
- xtgeo/include/eigen3/Eigen/Jacobi +32 -0
- xtgeo/include/eigen3/Eigen/KLUSupport +41 -0
- xtgeo/include/eigen3/Eigen/LU +47 -0
- xtgeo/include/eigen3/Eigen/MetisSupport +35 -0
- xtgeo/include/eigen3/Eigen/OrderingMethods +70 -0
- xtgeo/include/eigen3/Eigen/PaStiXSupport +49 -0
- xtgeo/include/eigen3/Eigen/PardisoSupport +35 -0
- xtgeo/include/eigen3/Eigen/QR +50 -0
- xtgeo/include/eigen3/Eigen/QtAlignedMalloc +39 -0
- xtgeo/include/eigen3/Eigen/SPQRSupport +34 -0
- xtgeo/include/eigen3/Eigen/SVD +50 -0
- xtgeo/include/eigen3/Eigen/Sparse +34 -0
- xtgeo/include/eigen3/Eigen/SparseCholesky +37 -0
- xtgeo/include/eigen3/Eigen/SparseCore +69 -0
- xtgeo/include/eigen3/Eigen/SparseLU +50 -0
- xtgeo/include/eigen3/Eigen/SparseQR +36 -0
- xtgeo/include/eigen3/Eigen/StdDeque +27 -0
- xtgeo/include/eigen3/Eigen/StdList +26 -0
- xtgeo/include/eigen3/Eigen/StdVector +27 -0
- xtgeo/include/eigen3/Eigen/SuperLUSupport +64 -0
- xtgeo/include/eigen3/Eigen/UmfPackSupport +40 -0
- xtgeo/include/eigen3/Eigen/src/Cholesky/LDLT.h +688 -0
- xtgeo/include/eigen3/Eigen/src/Cholesky/LLT.h +558 -0
- xtgeo/include/eigen3/Eigen/src/Cholesky/LLT_LAPACKE.h +99 -0
- xtgeo/include/eigen3/Eigen/src/CholmodSupport/CholmodSupport.h +682 -0
- xtgeo/include/eigen3/Eigen/src/Core/ArithmeticSequence.h +413 -0
- xtgeo/include/eigen3/Eigen/src/Core/Array.h +417 -0
- xtgeo/include/eigen3/Eigen/src/Core/ArrayBase.h +226 -0
- xtgeo/include/eigen3/Eigen/src/Core/ArrayWrapper.h +209 -0
- xtgeo/include/eigen3/Eigen/src/Core/Assign.h +90 -0
- xtgeo/include/eigen3/Eigen/src/Core/AssignEvaluator.h +1010 -0
- xtgeo/include/eigen3/Eigen/src/Core/Assign_MKL.h +178 -0
- xtgeo/include/eigen3/Eigen/src/Core/BandMatrix.h +353 -0
- xtgeo/include/eigen3/Eigen/src/Core/Block.h +448 -0
- xtgeo/include/eigen3/Eigen/src/Core/BooleanRedux.h +162 -0
- xtgeo/include/eigen3/Eigen/src/Core/CommaInitializer.h +164 -0
- xtgeo/include/eigen3/Eigen/src/Core/ConditionEstimator.h +175 -0
- xtgeo/include/eigen3/Eigen/src/Core/CoreEvaluators.h +1741 -0
- xtgeo/include/eigen3/Eigen/src/Core/CoreIterators.h +132 -0
- xtgeo/include/eigen3/Eigen/src/Core/CwiseBinaryOp.h +183 -0
- xtgeo/include/eigen3/Eigen/src/Core/CwiseNullaryOp.h +1001 -0
- xtgeo/include/eigen3/Eigen/src/Core/CwiseTernaryOp.h +197 -0
- xtgeo/include/eigen3/Eigen/src/Core/CwiseUnaryOp.h +103 -0
- xtgeo/include/eigen3/Eigen/src/Core/CwiseUnaryView.h +132 -0
- xtgeo/include/eigen3/Eigen/src/Core/DenseBase.h +701 -0
- xtgeo/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h +685 -0
- xtgeo/include/eigen3/Eigen/src/Core/DenseStorage.h +652 -0
- xtgeo/include/eigen3/Eigen/src/Core/Diagonal.h +258 -0
- xtgeo/include/eigen3/Eigen/src/Core/DiagonalMatrix.h +391 -0
- xtgeo/include/eigen3/Eigen/src/Core/DiagonalProduct.h +28 -0
- xtgeo/include/eigen3/Eigen/src/Core/Dot.h +318 -0
- xtgeo/include/eigen3/Eigen/src/Core/EigenBase.h +160 -0
- xtgeo/include/eigen3/Eigen/src/Core/ForceAlignedAccess.h +150 -0
- xtgeo/include/eigen3/Eigen/src/Core/Fuzzy.h +155 -0
- xtgeo/include/eigen3/Eigen/src/Core/GeneralProduct.h +465 -0
- xtgeo/include/eigen3/Eigen/src/Core/GenericPacketMath.h +1040 -0
- xtgeo/include/eigen3/Eigen/src/Core/GlobalFunctions.h +194 -0
- xtgeo/include/eigen3/Eigen/src/Core/IO.h +258 -0
- xtgeo/include/eigen3/Eigen/src/Core/IndexedView.h +237 -0
- xtgeo/include/eigen3/Eigen/src/Core/Inverse.h +117 -0
- xtgeo/include/eigen3/Eigen/src/Core/Map.h +171 -0
- xtgeo/include/eigen3/Eigen/src/Core/MapBase.h +310 -0
- xtgeo/include/eigen3/Eigen/src/Core/MathFunctions.h +2057 -0
- xtgeo/include/eigen3/Eigen/src/Core/MathFunctionsImpl.h +200 -0
- xtgeo/include/eigen3/Eigen/src/Core/Matrix.h +565 -0
- xtgeo/include/eigen3/Eigen/src/Core/MatrixBase.h +547 -0
- xtgeo/include/eigen3/Eigen/src/Core/NestByValue.h +85 -0
- xtgeo/include/eigen3/Eigen/src/Core/NoAlias.h +109 -0
- xtgeo/include/eigen3/Eigen/src/Core/NumTraits.h +335 -0
- xtgeo/include/eigen3/Eigen/src/Core/PartialReduxEvaluator.h +232 -0
- xtgeo/include/eigen3/Eigen/src/Core/PermutationMatrix.h +605 -0
- xtgeo/include/eigen3/Eigen/src/Core/PlainObjectBase.h +1128 -0
- xtgeo/include/eigen3/Eigen/src/Core/Product.h +191 -0
- xtgeo/include/eigen3/Eigen/src/Core/ProductEvaluators.h +1179 -0
- xtgeo/include/eigen3/Eigen/src/Core/Random.h +218 -0
- xtgeo/include/eigen3/Eigen/src/Core/Redux.h +515 -0
- xtgeo/include/eigen3/Eigen/src/Core/Ref.h +381 -0
- xtgeo/include/eigen3/Eigen/src/Core/Replicate.h +142 -0
- xtgeo/include/eigen3/Eigen/src/Core/Reshaped.h +454 -0
- xtgeo/include/eigen3/Eigen/src/Core/ReturnByValue.h +119 -0
- xtgeo/include/eigen3/Eigen/src/Core/Reverse.h +217 -0
- xtgeo/include/eigen3/Eigen/src/Core/Select.h +164 -0
- xtgeo/include/eigen3/Eigen/src/Core/SelfAdjointView.h +365 -0
- xtgeo/include/eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h +47 -0
- xtgeo/include/eigen3/Eigen/src/Core/Solve.h +188 -0
- xtgeo/include/eigen3/Eigen/src/Core/SolveTriangular.h +235 -0
- xtgeo/include/eigen3/Eigen/src/Core/SolverBase.h +168 -0
- xtgeo/include/eigen3/Eigen/src/Core/StableNorm.h +251 -0
- xtgeo/include/eigen3/Eigen/src/Core/StlIterators.h +463 -0
- xtgeo/include/eigen3/Eigen/src/Core/Stride.h +116 -0
- xtgeo/include/eigen3/Eigen/src/Core/Swap.h +68 -0
- xtgeo/include/eigen3/Eigen/src/Core/Transpose.h +464 -0
- xtgeo/include/eigen3/Eigen/src/Core/Transpositions.h +386 -0
- xtgeo/include/eigen3/Eigen/src/Core/TriangularMatrix.h +1001 -0
- xtgeo/include/eigen3/Eigen/src/Core/VectorBlock.h +96 -0
- xtgeo/include/eigen3/Eigen/src/Core/VectorwiseOp.h +784 -0
- xtgeo/include/eigen3/Eigen/src/Core/Visitor.h +381 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AVX/Complex.h +372 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AVX/MathFunctions.h +228 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AVX/PacketMath.h +1574 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AVX/TypeCasting.h +115 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AVX512/Complex.h +422 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AVX512/MathFunctions.h +362 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AVX512/PacketMath.h +2303 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AVX512/TypeCasting.h +89 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AltiVec/Complex.h +417 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AltiVec/MathFunctions.h +90 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +2937 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +221 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +629 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h +2711 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/CUDA/Complex.h +258 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/Default/BFloat16.h +700 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/Default/ConjHelper.h +117 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +1649 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +110 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/Default/Half.h +942 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/Default/Settings.h +49 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/Default/TypeCasting.h +120 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/GPU/MathFunctions.h +103 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/GPU/PacketMath.h +1685 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/GPU/TypeCasting.h +80 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/HIP/hcc/math_constants.h +23 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/MSA/Complex.h +648 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/MSA/MathFunctions.h +387 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/MSA/PacketMath.h +1233 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/NEON/Complex.h +584 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +183 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/NEON/MathFunctions.h +75 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/NEON/PacketMath.h +4587 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/NEON/TypeCasting.h +1419 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SSE/Complex.h +351 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h +199 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SSE/PacketMath.h +1505 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SSE/TypeCasting.h +142 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SVE/MathFunctions.h +44 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SVE/PacketMath.h +752 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SVE/TypeCasting.h +49 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SYCL/InteropHeaders.h +232 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SYCL/MathFunctions.h +301 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SYCL/PacketMath.h +670 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h +694 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/SYCL/TypeCasting.h +85 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/ZVector/Complex.h +426 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/ZVector/MathFunctions.h +233 -0
- xtgeo/include/eigen3/Eigen/src/Core/arch/ZVector/PacketMath.h +1060 -0
- xtgeo/include/eigen3/Eigen/src/Core/functors/AssignmentFunctors.h +177 -0
- xtgeo/include/eigen3/Eigen/src/Core/functors/BinaryFunctors.h +541 -0
- xtgeo/include/eigen3/Eigen/src/Core/functors/NullaryFunctors.h +189 -0
- xtgeo/include/eigen3/Eigen/src/Core/functors/StlFunctors.h +166 -0
- xtgeo/include/eigen3/Eigen/src/Core/functors/TernaryFunctors.h +25 -0
- xtgeo/include/eigen3/Eigen/src/Core/functors/UnaryFunctors.h +1131 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h +2645 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h +517 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +317 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +145 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +124 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/GeneralMatrixVector.h +518 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +136 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/Parallelizer.h +180 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +544 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +295 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h +262 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +118 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/SelfadjointProduct.h +133 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h +94 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h +472 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +317 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/TriangularMatrixVector.h +350 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +255 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h +337 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +167 -0
- xtgeo/include/eigen3/Eigen/src/Core/products/TriangularSolverVector.h +148 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/BlasUtil.h +583 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/ConfigureVectorization.h +512 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/Constants.h +563 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/DisableStupidWarnings.h +106 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/ForwardDeclarations.h +322 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/IndexedViewHelper.h +186 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/IntegralConstant.h +272 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/MKL_support.h +137 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/Macros.h +1464 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/Memory.h +1163 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/Meta.h +812 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/NonMPL2.h +3 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h +31 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/ReshapedHelper.h +51 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/StaticAssert.h +221 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/SymbolicIndex.h +293 -0
- xtgeo/include/eigen3/Eigen/src/Core/util/XprHelper.h +856 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h +346 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/ComplexSchur.h +462 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +91 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/EigenSolver.h +622 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +418 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +226 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h +374 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +158 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/RealQZ.h +657 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/RealSchur.h +558 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +77 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +904 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +87 -0
- xtgeo/include/eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h +561 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/AlignedBox.h +486 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/AngleAxis.h +247 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/EulerAngles.h +114 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/Homogeneous.h +501 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/Hyperplane.h +282 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/OrthoMethods.h +235 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/ParametrizedLine.h +232 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/Quaternion.h +870 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/Rotation2D.h +199 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/RotationBase.h +206 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/Scaling.h +188 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/Transform.h +1563 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/Translation.h +202 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/Umeyama.h +166 -0
- xtgeo/include/eigen3/Eigen/src/Geometry/arch/Geometry_SIMD.h +168 -0
- xtgeo/include/eigen3/Eigen/src/Householder/BlockHouseholder.h +110 -0
- xtgeo/include/eigen3/Eigen/src/Householder/Householder.h +176 -0
- xtgeo/include/eigen3/Eigen/src/Householder/HouseholderSequence.h +545 -0
- xtgeo/include/eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +226 -0
- xtgeo/include/eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +212 -0
- xtgeo/include/eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +229 -0
- xtgeo/include/eigen3/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +394 -0
- xtgeo/include/eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +453 -0
- xtgeo/include/eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +444 -0
- xtgeo/include/eigen3/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +198 -0
- xtgeo/include/eigen3/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +117 -0
- xtgeo/include/eigen3/Eigen/src/Jacobi/Jacobi.h +483 -0
- xtgeo/include/eigen3/Eigen/src/KLUSupport/KLUSupport.h +358 -0
- xtgeo/include/eigen3/Eigen/src/LU/Determinant.h +117 -0
- xtgeo/include/eigen3/Eigen/src/LU/FullPivLU.h +877 -0
- xtgeo/include/eigen3/Eigen/src/LU/InverseImpl.h +432 -0
- xtgeo/include/eigen3/Eigen/src/LU/PartialPivLU.h +624 -0
- xtgeo/include/eigen3/Eigen/src/LU/PartialPivLU_LAPACKE.h +83 -0
- xtgeo/include/eigen3/Eigen/src/LU/arch/InverseSize4.h +351 -0
- xtgeo/include/eigen3/Eigen/src/MetisSupport/MetisSupport.h +137 -0
- xtgeo/include/eigen3/Eigen/src/OrderingMethods/Amd.h +435 -0
- xtgeo/include/eigen3/Eigen/src/OrderingMethods/Eigen_Colamd.h +1863 -0
- xtgeo/include/eigen3/Eigen/src/OrderingMethods/Ordering.h +153 -0
- xtgeo/include/eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h +678 -0
- xtgeo/include/eigen3/Eigen/src/PardisoSupport/PardisoSupport.h +545 -0
- xtgeo/include/eigen3/Eigen/src/QR/ColPivHouseholderQR.h +674 -0
- xtgeo/include/eigen3/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +97 -0
- xtgeo/include/eigen3/Eigen/src/QR/CompleteOrthogonalDecomposition.h +635 -0
- xtgeo/include/eigen3/Eigen/src/QR/FullPivHouseholderQR.h +713 -0
- xtgeo/include/eigen3/Eigen/src/QR/HouseholderQR.h +434 -0
- xtgeo/include/eigen3/Eigen/src/QR/HouseholderQR_LAPACKE.h +68 -0
- xtgeo/include/eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +335 -0
- xtgeo/include/eigen3/Eigen/src/SVD/BDCSVD.h +1366 -0
- xtgeo/include/eigen3/Eigen/src/SVD/JacobiSVD.h +812 -0
- xtgeo/include/eigen3/Eigen/src/SVD/JacobiSVD_LAPACKE.h +91 -0
- xtgeo/include/eigen3/Eigen/src/SVD/SVDBase.h +376 -0
- xtgeo/include/eigen3/Eigen/src/SVD/UpperBidiagonalization.h +414 -0
- xtgeo/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h +697 -0
- xtgeo/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +174 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/AmbiVector.h +378 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/CompressedStorage.h +274 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +352 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h +67 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseAssign.h +270 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseBlock.h +571 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseColEtree.h +206 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseCompressedBase.h +370 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +722 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +150 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseDenseProduct.h +342 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h +138 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseDot.h +98 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseFuzzy.h +29 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseMap.h +305 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseMatrix.h +1518 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseMatrixBase.h +398 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparsePermutation.h +178 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseProduct.h +181 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseRedux.h +49 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseRef.h +397 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h +659 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseSolverBase.h +124 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +198 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseTranspose.h +92 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseTriangularView.h +189 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseUtil.h +186 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseVector.h +478 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/SparseView.h +254 -0
- xtgeo/include/eigen3/Eigen/src/SparseCore/TriangularSolver.h +315 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU.h +923 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLUImpl.h +66 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_Memory.h +226 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_Structs.h +110 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +375 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_Utils.h +80 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_column_bmod.h +181 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_column_dfs.h +179 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +107 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +280 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +126 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +130 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_panel_bmod.h +223 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_panel_dfs.h +258 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h +137 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_pruneL.h +136 -0
- xtgeo/include/eigen3/Eigen/src/SparseLU/SparseLU_relax_snode.h +83 -0
- xtgeo/include/eigen3/Eigen/src/SparseQR/SparseQR.h +758 -0
- xtgeo/include/eigen3/Eigen/src/StlSupport/StdDeque.h +116 -0
- xtgeo/include/eigen3/Eigen/src/StlSupport/StdList.h +106 -0
- xtgeo/include/eigen3/Eigen/src/StlSupport/StdVector.h +131 -0
- xtgeo/include/eigen3/Eigen/src/StlSupport/details.h +84 -0
- xtgeo/include/eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h +1025 -0
- xtgeo/include/eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h +642 -0
- xtgeo/include/eigen3/Eigen/src/misc/Image.h +82 -0
- xtgeo/include/eigen3/Eigen/src/misc/Kernel.h +79 -0
- xtgeo/include/eigen3/Eigen/src/misc/RealSvd2x2.h +55 -0
- xtgeo/include/eigen3/Eigen/src/misc/blas.h +440 -0
- xtgeo/include/eigen3/Eigen/src/misc/lapack.h +152 -0
- xtgeo/include/eigen3/Eigen/src/misc/lapacke.h +16292 -0
- xtgeo/include/eigen3/Eigen/src/misc/lapacke_mangling.h +17 -0
- xtgeo/include/eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h +358 -0
- xtgeo/include/eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h +696 -0
- xtgeo/include/eigen3/Eigen/src/plugins/BlockMethods.h +1442 -0
- xtgeo/include/eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h +115 -0
- xtgeo/include/eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h +177 -0
- xtgeo/include/eigen3/Eigen/src/plugins/IndexedViewMethods.h +262 -0
- xtgeo/include/eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h +152 -0
- xtgeo/include/eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h +95 -0
- xtgeo/include/eigen3/Eigen/src/plugins/ReshapedMethods.h +149 -0
- xtgeo/include/eigen3/signature_of_eigen3_matrix_library +1 -0
- xtgeo/include/eigen3/unsupported/Eigen/AdolcForward +159 -0
- xtgeo/include/eigen3/unsupported/Eigen/AlignedVector3 +234 -0
- xtgeo/include/eigen3/unsupported/Eigen/ArpackSupport +30 -0
- xtgeo/include/eigen3/unsupported/Eigen/AutoDiff +46 -0
- xtgeo/include/eigen3/unsupported/Eigen/BVH +95 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/Tensor +137 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/TensorSymmetry +42 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/ThreadPool +74 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/Tensor.h +554 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorArgMax.h +329 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorAssign.h +247 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h +1176 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorBlock.h +1559 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h +1093 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h +518 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h +377 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h +1023 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h +73 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionCuda.h +6 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionGpu.h +1413 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h +575 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionSycl.h +1650 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h +1679 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h +456 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h +1132 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConvolutionSycl.h +544 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorCostModel.h +214 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorCustomOp.h +347 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDevice.h +137 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceCuda.h +6 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h +104 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h +389 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h +1048 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h +409 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDimensionList.h +236 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h +490 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h +236 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h +983 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h +703 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorExpr.h +388 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h +669 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h +379 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h +237 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h +191 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h +488 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorGenerator.h +302 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorGlobalFunctions.h +33 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaDefines.h +99 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaUndefines.h +44 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +79 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorImagePatch.h +603 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h +738 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorInflation.h +247 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h +82 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h +263 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorLayoutSwap.h +216 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h +98 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h +327 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h +311 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h +1102 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h +708 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorPatch.h +291 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h +322 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h +998 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReductionCuda.h +6 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReductionGpu.h +966 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h +582 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorRef.h +454 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h +465 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorScan.h +528 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorScanSycl.h +513 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h +471 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h +161 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h +346 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorTrace.h +303 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h +264 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h +249 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorVolumePatch.h +629 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/DynamicSymmetry.h +293 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/StaticSymmetry.h +236 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/Symmetry.h +338 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/util/TemplateGroupTheory.h +669 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/Barrier.h +67 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/EventCount.h +249 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h +486 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h +236 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadCancel.h +23 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h +40 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadLocal.h +301 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h +48 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadYield.h +20 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/util/CXX11Meta.h +537 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/util/CXX11Workarounds.h +88 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/util/EmulateArray.h +261 -0
- xtgeo/include/eigen3/unsupported/Eigen/CXX11/src/util/MaxSizeVector.h +158 -0
- xtgeo/include/eigen3/unsupported/Eigen/EulerAngles +43 -0
- xtgeo/include/eigen3/unsupported/Eigen/FFT +419 -0
- xtgeo/include/eigen3/unsupported/Eigen/IterativeSolvers +51 -0
- xtgeo/include/eigen3/unsupported/Eigen/KroneckerProduct +36 -0
- xtgeo/include/eigen3/unsupported/Eigen/LevenbergMarquardt +49 -0
- xtgeo/include/eigen3/unsupported/Eigen/MPRealSupport +213 -0
- xtgeo/include/eigen3/unsupported/Eigen/MatrixFunctions +504 -0
- xtgeo/include/eigen3/unsupported/Eigen/MoreVectorization +24 -0
- xtgeo/include/eigen3/unsupported/Eigen/NonLinearOptimization +140 -0
- xtgeo/include/eigen3/unsupported/Eigen/NumericalDiff +56 -0
- xtgeo/include/eigen3/unsupported/Eigen/OpenGLSupport +322 -0
- xtgeo/include/eigen3/unsupported/Eigen/Polynomials +137 -0
- xtgeo/include/eigen3/unsupported/Eigen/Skyline +39 -0
- xtgeo/include/eigen3/unsupported/Eigen/SparseExtra +54 -0
- xtgeo/include/eigen3/unsupported/Eigen/SpecialFunctions +103 -0
- xtgeo/include/eigen3/unsupported/Eigen/Splines +35 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h +108 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h +730 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h +220 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/BVH/BVAlgorithms.h +293 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/BVH/KdBVH.h +223 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h +790 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/EulerAngles/EulerAngles.h +355 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/EulerAngles/EulerSystem.h +305 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/FFT/ei_fftw_impl.h +261 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/FFT/ei_kissfft_impl.h +449 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h +187 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/IterativeSolvers/DGMRES.h +511 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/IterativeSolvers/GMRES.h +335 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/IterativeSolvers/IDRS.h +436 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h +90 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/IterativeSolvers/IterationController.h +154 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/IterativeSolvers/MINRES.h +267 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/IterativeSolvers/Scaling.h +193 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h +305 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h +84 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h +202 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMpar.h +160 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h +188 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h +396 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h +441 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h +569 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h +373 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h +705 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h +368 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/MatrixFunctions/StemFunction.h +117 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/MoreVectorization/MathFunctions.h +95 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h +601 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h +657 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/chkder.h +66 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/covar.h +70 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/dogleg.h +107 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/fdjac1.h +79 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/lmpar.h +298 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h +91 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h +30 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/r1updt.h +99 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NonLinearOptimization/rwupdt.h +49 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h +130 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Polynomials/Companion.h +280 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Polynomials/PolynomialSolver.h +428 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Polynomials/PolynomialUtils.h +143 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h +352 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Skyline/SkylineMatrix.h +862 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h +212 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Skyline/SkylineProduct.h +295 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Skyline/SkylineStorage.h +259 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Skyline/SkylineUtil.h +89 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h +122 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SparseExtra/BlockSparseMatrix.h +1079 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h +404 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SparseExtra/MarketIO.h +282 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h +247 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SparseExtra/RandomSetter.h +349 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsArrayAPI.h +286 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsBFloat16.h +68 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsFunctors.h +357 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsHalf.h +66 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsImpl.h +1959 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsPacketMath.h +118 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/HipVectorCompatibility.h +67 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsArrayAPI.h +167 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsBFloat16.h +58 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsFunctors.h +330 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsHalf.h +58 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h +2045 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsPacketMath.h +79 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/AVX/BesselFunctions.h +46 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/AVX/SpecialFunctions.h +16 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/AVX512/BesselFunctions.h +46 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/AVX512/SpecialFunctions.h +16 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/GPU/SpecialFunctions.h +369 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/NEON/BesselFunctions.h +54 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/NEON/SpecialFunctions.h +34 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Splines/Spline.h +507 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Splines/SplineFitting.h +431 -0
- xtgeo/include/eigen3/unsupported/Eigen/src/Splines/SplineFwd.h +93 -0
- xtgeo/io/__init__.py +1 -0
- xtgeo/io/_file.py +594 -0
- xtgeo/metadata/__init__.py +17 -0
- xtgeo/metadata/metadata.py +435 -0
- xtgeo/roxutils/__init__.py +7 -0
- xtgeo/roxutils/_roxar_loader.py +54 -0
- xtgeo/roxutils/_roxutils_etc.py +122 -0
- xtgeo/roxutils/roxutils.py +207 -0
- xtgeo/share/eigen3/cmake/Eigen3Config.cmake +37 -0
- xtgeo/share/eigen3/cmake/Eigen3ConfigVersion.cmake +65 -0
- xtgeo/share/eigen3/cmake/Eigen3Targets.cmake +106 -0
- xtgeo/share/eigen3/cmake/UseEigen3.cmake +6 -0
- xtgeo/share/pkgconfig/eigen3.pc +9 -0
- xtgeo/surface/__init__.py +18 -0
- xtgeo/surface/_regsurf_boundary.py +26 -0
- xtgeo/surface/_regsurf_cube.py +210 -0
- xtgeo/surface/_regsurf_cube_window.py +391 -0
- xtgeo/surface/_regsurf_cube_window_v2.py +297 -0
- xtgeo/surface/_regsurf_cube_window_v3.py +360 -0
- xtgeo/surface/_regsurf_export.py +388 -0
- xtgeo/surface/_regsurf_grid3d.py +275 -0
- xtgeo/surface/_regsurf_gridding.py +347 -0
- xtgeo/surface/_regsurf_ijxyz_parser.py +278 -0
- xtgeo/surface/_regsurf_import.py +347 -0
- xtgeo/surface/_regsurf_lowlevel.py +122 -0
- xtgeo/surface/_regsurf_oper.py +538 -0
- xtgeo/surface/_regsurf_roxapi.py +241 -0
- xtgeo/surface/_regsurf_utils.py +81 -0
- xtgeo/surface/_surfs_import.py +43 -0
- xtgeo/surface/_zmap_parser.py +138 -0
- xtgeo/surface/regular_surface.py +2962 -0
- xtgeo/surface/surfaces.py +276 -0
- xtgeo/well/__init__.py +24 -0
- xtgeo/well/_blockedwell_roxapi.py +241 -0
- xtgeo/well/_blockedwells_roxapi.py +68 -0
- xtgeo/well/_well_aux.py +30 -0
- xtgeo/well/_well_io.py +327 -0
- xtgeo/well/_well_oper.py +483 -0
- xtgeo/well/_well_roxapi.py +304 -0
- xtgeo/well/_wellmarkers.py +486 -0
- xtgeo/well/_wells_utils.py +158 -0
- xtgeo/well/blocked_well.py +220 -0
- xtgeo/well/blocked_wells.py +134 -0
- xtgeo/well/well1.py +1516 -0
- xtgeo/well/wells.py +211 -0
- xtgeo/xyz/__init__.py +6 -0
- xtgeo/xyz/_polygons_oper.py +272 -0
- xtgeo/xyz/_xyz.py +758 -0
- xtgeo/xyz/_xyz_data.py +646 -0
- xtgeo/xyz/_xyz_io.py +737 -0
- xtgeo/xyz/_xyz_lowlevel.py +42 -0
- xtgeo/xyz/_xyz_oper.py +613 -0
- xtgeo/xyz/_xyz_roxapi.py +766 -0
- xtgeo/xyz/points.py +698 -0
- xtgeo/xyz/polygons.py +827 -0
- xtgeo-4.13.1.dist-info/METADATA +146 -0
- xtgeo-4.13.1.dist-info/RECORD +654 -0
- xtgeo-4.13.1.dist-info/WHEEL +6 -0
- xtgeo-4.13.1.dist-info/licenses/LICENSE.md +165 -0
- xtgeo.libs/libgomp-a49a47f9.so.1.0.0 +0 -0
|
@@ -0,0 +1,2962 @@
|
|
|
1
|
+
"""Module/class for regular surfaces with XTGeo.
|
|
2
|
+
|
|
3
|
+
Regular surfaces have a constant distance between nodes (xinc, yinc),
|
|
4
|
+
and this simplifies computations a lot. A regular surface is
|
|
5
|
+
defined by an origin (xori, yori)
|
|
6
|
+
in UTM, a number of columns (along X axis, if no rotation), a number of
|
|
7
|
+
rows (along Y axis if no rotation), and increment (distance between nodes).
|
|
8
|
+
|
|
9
|
+
The map itself is an array of values.
|
|
10
|
+
|
|
11
|
+
Rotation is allowed and is measured in degrees, anticlock from X axis.
|
|
12
|
+
|
|
13
|
+
Note that an instance of a regular surface can be made directly with::
|
|
14
|
+
|
|
15
|
+
>>> import xtgeo
|
|
16
|
+
>>> mysurf = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
17
|
+
|
|
18
|
+
or::
|
|
19
|
+
|
|
20
|
+
mysurf = xtgeo.surface_from_roxar('some_rms_project', 'TopX', 'DepthSurface')
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
# --------------------------------------------------------------------------------------
|
|
25
|
+
# Comment on 'asmasked' vs 'activeonly:
|
|
26
|
+
# 'asmasked'=True will return a np.ma array, with some fill_value if
|
|
27
|
+
# if asmasked = False
|
|
28
|
+
#
|
|
29
|
+
# while 'activeonly' will filter
|
|
30
|
+
# out maked entries, or use np.nan if 'activeonly' is False
|
|
31
|
+
#
|
|
32
|
+
# For functions with mask=... ,the should be replaced with asmasked=...
|
|
33
|
+
# --------------------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
from __future__ import annotations
|
|
36
|
+
|
|
37
|
+
import functools
|
|
38
|
+
import math
|
|
39
|
+
import numbers
|
|
40
|
+
import warnings
|
|
41
|
+
from copy import deepcopy
|
|
42
|
+
from types import FunctionType
|
|
43
|
+
from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Tuple, Type, Union
|
|
44
|
+
|
|
45
|
+
import numpy as np
|
|
46
|
+
import numpy.ma as ma
|
|
47
|
+
import pandas as pd
|
|
48
|
+
import scipy.ndimage
|
|
49
|
+
|
|
50
|
+
from xtgeo.common.constants import (
|
|
51
|
+
UNDEF,
|
|
52
|
+
UNDEF_LIMIT,
|
|
53
|
+
VERYLARGENEGATIVE,
|
|
54
|
+
VERYLARGEPOSITIVE,
|
|
55
|
+
)
|
|
56
|
+
from xtgeo.common.exceptions import InvalidFileFormatError
|
|
57
|
+
from xtgeo.common.log import null_logger
|
|
58
|
+
from xtgeo.common.sys import generic_hash
|
|
59
|
+
from xtgeo.common.xtgeo_dialog import XTGDescription, XTGeoDialog
|
|
60
|
+
from xtgeo.io._file import FileFormat, FileWrapper
|
|
61
|
+
from xtgeo.metadata.metadata import MetaDataRegularSurface
|
|
62
|
+
from xtgeo.xyz.points import Points
|
|
63
|
+
|
|
64
|
+
from . import (
|
|
65
|
+
_regsurf_boundary,
|
|
66
|
+
_regsurf_cube,
|
|
67
|
+
_regsurf_cube_window,
|
|
68
|
+
_regsurf_export,
|
|
69
|
+
_regsurf_grid3d,
|
|
70
|
+
_regsurf_gridding,
|
|
71
|
+
_regsurf_import,
|
|
72
|
+
_regsurf_oper,
|
|
73
|
+
_regsurf_roxapi,
|
|
74
|
+
_regsurf_utils,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
if TYPE_CHECKING:
|
|
78
|
+
import io
|
|
79
|
+
import pathlib
|
|
80
|
+
|
|
81
|
+
from xtgeo.cube.cube1 import Cube
|
|
82
|
+
from xtgeo.grid3d.grid import Grid, GridProperty
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
xtg = XTGeoDialog()
|
|
86
|
+
logger = null_logger(__name__)
|
|
87
|
+
|
|
88
|
+
# valid argumentts for seismic attributes
|
|
89
|
+
ValidAttrs = Literal[
|
|
90
|
+
"all",
|
|
91
|
+
"max",
|
|
92
|
+
"min",
|
|
93
|
+
"rms",
|
|
94
|
+
"mean",
|
|
95
|
+
"var",
|
|
96
|
+
"maxpos",
|
|
97
|
+
"maxneg",
|
|
98
|
+
"sumpos",
|
|
99
|
+
"sumneg",
|
|
100
|
+
"meanabs",
|
|
101
|
+
"meanpos",
|
|
102
|
+
"meanneg",
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
# ======================================================================================
|
|
106
|
+
# METHODS as wrappers to class init + import
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def surface_from_file(
|
|
110
|
+
mfile,
|
|
111
|
+
fformat=None,
|
|
112
|
+
template=None,
|
|
113
|
+
values=True,
|
|
114
|
+
engine: Optional[str] = None,
|
|
115
|
+
dtype: Union[Type[np.float64], Type[np.float32]] = np.float64,
|
|
116
|
+
):
|
|
117
|
+
"""Make an instance of a RegularSurface directly from file import.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
mfile (str): Name of file
|
|
121
|
+
fformat: File format, None/guess/irap_binary/irap_ascii/ijxyz/petromod/
|
|
122
|
+
zmap_ascii/xtg/hdf is currently supported. If None or guess, the file
|
|
123
|
+
'signature' is used to guess format first, then file extension.
|
|
124
|
+
template: Only valid if ``ijxyz`` format, where an existing Cube or
|
|
125
|
+
RegularSurface instance is applied to get correct topology.
|
|
126
|
+
values (bool): If True (default), surface values will be read (Irap binary only)
|
|
127
|
+
engine (str): Key indended for developers initially, now deprecated and have no
|
|
128
|
+
effect. To be removed in future versions.
|
|
129
|
+
dtype: Requsted numpy dtype of values; default is float64, alternatively float32
|
|
130
|
+
|
|
131
|
+
Example::
|
|
132
|
+
|
|
133
|
+
>>> import xtgeo
|
|
134
|
+
>>> mysurf = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
135
|
+
|
|
136
|
+
.. versionchanged:: 2.1
|
|
137
|
+
Key "values" for Irap binary maps added
|
|
138
|
+
|
|
139
|
+
.. versionchanged:: 2.13 Key "engine" added
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
return RegularSurface._read_file(
|
|
143
|
+
mfile,
|
|
144
|
+
fformat=fformat,
|
|
145
|
+
load_values=values,
|
|
146
|
+
template=template,
|
|
147
|
+
dtype=dtype,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def surface_from_roxar(
|
|
152
|
+
project,
|
|
153
|
+
name,
|
|
154
|
+
category,
|
|
155
|
+
stype="horizons",
|
|
156
|
+
realisation=0,
|
|
157
|
+
dtype: Union[Type[np.float64], Type[np.float32]] = np.float64,
|
|
158
|
+
):
|
|
159
|
+
"""This makes an instance of a RegularSurface directly from roxar input.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
project (str or special): Name of project (as folder) if
|
|
163
|
+
outside RMS, og just use the magic project word if within RMS.
|
|
164
|
+
name (str): Name of surface/map
|
|
165
|
+
category (str): For horizons/zones or clipboard/general2d_data:
|
|
166
|
+
for example 'DS_extracted'. For clipboard/general2d_data this can
|
|
167
|
+
be empty or None, or use '/' for multiple folder levels (e.g. 'fld/subfld').
|
|
168
|
+
For 'trends', the category is not applied.
|
|
169
|
+
stype (str): RMS folder type, 'horizons' (default), 'zones', 'clipboard',
|
|
170
|
+
'general2d_data' or 'trends'
|
|
171
|
+
realisation (int): Realisation number, default is 0
|
|
172
|
+
dtype: Requested numpy dtype for array; default is 64 bit
|
|
173
|
+
|
|
174
|
+
Example::
|
|
175
|
+
|
|
176
|
+
# inside RMS:
|
|
177
|
+
import xtgeo
|
|
178
|
+
mysurf = xtgeo.surface_from_roxar(project, 'TopEtive', 'DepthSurface')
|
|
179
|
+
|
|
180
|
+
Note::
|
|
181
|
+
|
|
182
|
+
When dealing with surfaces to and from ``stype="trends"``, the surface must
|
|
183
|
+
exist in advance, i.e. the Roxar API do not allow creating new surfaces.
|
|
184
|
+
Actually trends are read only, but a workaround using ``load()`` in Roxar
|
|
185
|
+
API makes it possible to overwrite existing surface trends. In addition,
|
|
186
|
+
``realisation`` is not applied in trends.
|
|
187
|
+
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
return RegularSurface._read_roxar(
|
|
191
|
+
project, name, category, stype=stype, realisation=realisation, dtype=dtype
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def surface_from_cube(cube, value):
|
|
196
|
+
"""Make RegularSurface directly from a cube instance with a constant value.
|
|
197
|
+
|
|
198
|
+
The surface geometry will be exactly the same as for the Cube.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
cube(xtgeo.cube.Cube): A Cube instance
|
|
202
|
+
value (float): A constant value for the surface
|
|
203
|
+
|
|
204
|
+
Example::
|
|
205
|
+
|
|
206
|
+
>>> import xtgeo
|
|
207
|
+
>>> mycube = xtgeo.cube_from_file(cube_dir + "/ib_test_cube2.segy")
|
|
208
|
+
>>> mymap = xtgeo.surface_from_cube(mycube, 2700)
|
|
209
|
+
|
|
210
|
+
"""
|
|
211
|
+
return RegularSurface._read_cube(cube, value)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def surface_from_grid3d(
|
|
215
|
+
grid: Grid,
|
|
216
|
+
template: RegularSurface | str | None = None,
|
|
217
|
+
where: str | int = "top",
|
|
218
|
+
property: str | GridProperty = "depth",
|
|
219
|
+
rfactor: float = 1.0,
|
|
220
|
+
index_position: Literal["center", "top", "base"] = "center",
|
|
221
|
+
**kwargs,
|
|
222
|
+
) -> RegularSurface | List[np.ndarray]:
|
|
223
|
+
"""This makes an instance of a RegularSurface directly from a Grid() instance.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
grid: XTGeo 3D Grid instance, describing the corner point grid geometry
|
|
227
|
+
template: Optional, to use an existing surface as
|
|
228
|
+
template for map geometry, or by using "native" which returns a surface that
|
|
229
|
+
approximate the 3D grid layout (same number of rows and columns, and same
|
|
230
|
+
rotation). If None (default) a non-rotated surface will be made
|
|
231
|
+
based on a refined estimation from the current grid
|
|
232
|
+
resolution (see ``rfactor``).
|
|
233
|
+
where: Cell layer number, or if property is "depth", use "top" or "base" to get
|
|
234
|
+
a surface sampled from the very top or very base of the grid (including
|
|
235
|
+
inactive cells!). Otherwise use the syntax "2_top" where 2
|
|
236
|
+
is layer no. 2 and _top indicates top of cell, while "_base"
|
|
237
|
+
indicates base of cell. Cell layer numbering starts from 1. Default position
|
|
238
|
+
in a cell layer is "top" if layer is given as pure number and "depth" is
|
|
239
|
+
the property. If a grid property is given, the position is always found
|
|
240
|
+
the center depth within in a cell.
|
|
241
|
+
property: Which property to return. Choices are "depth", "i"
|
|
242
|
+
(columns) or "j" (rows) or, more generic, a GridProperty instance
|
|
243
|
+
which belongs to the given grid geometry. Alle these returns a
|
|
244
|
+
RegularSurface. A special variant is "raw" which
|
|
245
|
+
returns a list of 2D numpy arrays. See details in the Note section.
|
|
246
|
+
rfactor: Note this setting will only apply if ``template`` is None.
|
|
247
|
+
Determines how fine the extracted map is; higher values
|
|
248
|
+
for finer map (but computing time will increase slightly).
|
|
249
|
+
The default is 1.0, which in effect will make a surface approximentaly
|
|
250
|
+
twice as fine as the average resolution estimated from the 3D grid.
|
|
251
|
+
index_position: Default is "center" which means that the index is taken
|
|
252
|
+
from the Z center of the cell. If "top" is given, the index is taken from
|
|
253
|
+
the top of the cell, and if "base" is given, the index is taken from the
|
|
254
|
+
base of the cell. This is only valid for index properties "i" and "j".
|
|
255
|
+
|
|
256
|
+
Note::
|
|
257
|
+
The keyword ``mode`` is deprecated and will be removed in XTGeo version 5,
|
|
258
|
+
use keyword ``property`` instead. If both are given, ``property`` will be used.
|
|
259
|
+
|
|
260
|
+
Note::
|
|
261
|
+
For ``property`` "depth", "i" and "j", all cells in a layer will be used
|
|
262
|
+
(including inactive 3D cells), while for a GridProperty, only active cells
|
|
263
|
+
will be used. Hence the extent of the resulting surfaces may differ.
|
|
264
|
+
|
|
265
|
+
Note::
|
|
266
|
+
For ``property`` "raw", the return is a list of 2D arrays, where the first
|
|
267
|
+
array is the i-index (int), the second is the j-index (int), the third is the
|
|
268
|
+
top depth (float64), the fourth is the bottom depth (float64), and the
|
|
269
|
+
fifth is a mask (boolean) for inactive cells. For the index arrays, -1
|
|
270
|
+
indicates that the cell is outside any grid cell (projected from above; i.e.
|
|
271
|
+
could also be within a fault). For the depth arrays, the value is NaN
|
|
272
|
+
for inactive cells. The inactive mask is True for inactive cells. The index
|
|
273
|
+
arrays and mask is derived from the Z midpoints of the 3D cells. The "raw"
|
|
274
|
+
option is useful for further processing in Python, e.g. when a combination
|
|
275
|
+
of properties is needed.
|
|
276
|
+
|
|
277
|
+
.. versionadded:: 2.1
|
|
278
|
+
.. versionchanged:: 4.2 Changed ``mode`` to ``property`` to add support for
|
|
279
|
+
a GridProperty. The ``where`` arg. can now be an integer.
|
|
280
|
+
Added option ``activeonly``.
|
|
281
|
+
.. versionchanged:: 4.3 Added option ``raw`` to get data for further processing.
|
|
282
|
+
and add ``index_position`` for "i" and "j" properties.
|
|
283
|
+
"""
|
|
284
|
+
mode = kwargs.get("mode")
|
|
285
|
+
if mode is not None:
|
|
286
|
+
warnings.warn(
|
|
287
|
+
"The 'mode' argument is deprecated, use 'property' instead",
|
|
288
|
+
DeprecationWarning,
|
|
289
|
+
stacklevel=2,
|
|
290
|
+
)
|
|
291
|
+
property = mode
|
|
292
|
+
|
|
293
|
+
if isinstance(property, str) and property == "raw":
|
|
294
|
+
args = _regsurf_grid3d.from_grid3d(
|
|
295
|
+
grid, template, where, property, rfactor, index_position="center"
|
|
296
|
+
)
|
|
297
|
+
return args["values"]
|
|
298
|
+
|
|
299
|
+
return RegularSurface._read_grid3d(
|
|
300
|
+
grid, template, where, property, rfactor, index_position
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def _data_reader_factory(file_format: FileFormat):
|
|
305
|
+
if file_format == FileFormat.IRAP_BINARY:
|
|
306
|
+
return _regsurf_import.import_irap_binary
|
|
307
|
+
if file_format == FileFormat.IRAP_ASCII:
|
|
308
|
+
return _regsurf_import.import_irap_ascii
|
|
309
|
+
if file_format == FileFormat.IJXYZ:
|
|
310
|
+
return _regsurf_import.import_ijxyz
|
|
311
|
+
if file_format == FileFormat.PETROMOD:
|
|
312
|
+
return _regsurf_import.import_petromod
|
|
313
|
+
if file_format == FileFormat.ZMAP_ASCII:
|
|
314
|
+
return _regsurf_import.import_zmap_ascii
|
|
315
|
+
if file_format == FileFormat.XTG:
|
|
316
|
+
return _regsurf_import.import_xtg
|
|
317
|
+
if file_format == FileFormat.HDF:
|
|
318
|
+
return _regsurf_import.import_hdf5_regsurf
|
|
319
|
+
|
|
320
|
+
extensions = FileFormat.extensions_string(
|
|
321
|
+
[
|
|
322
|
+
FileFormat.IRAP_BINARY,
|
|
323
|
+
FileFormat.IRAP_ASCII,
|
|
324
|
+
FileFormat.IJXYZ,
|
|
325
|
+
FileFormat.PETROMOD,
|
|
326
|
+
FileFormat.ZMAP_ASCII,
|
|
327
|
+
FileFormat.XTG,
|
|
328
|
+
FileFormat.HDF,
|
|
329
|
+
]
|
|
330
|
+
)
|
|
331
|
+
raise InvalidFileFormatError(
|
|
332
|
+
f"File format {file_format} is invalid for type RegularSurface. "
|
|
333
|
+
f"Supported formats are {extensions}."
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
class RegularSurface:
|
|
338
|
+
"""Class for a regular surface in the XTGeo framework.
|
|
339
|
+
|
|
340
|
+
The values can as default be accessed by the user as a 2D masked numpy
|
|
341
|
+
(ncol, nrow) float64 array, but also other representations or views are
|
|
342
|
+
possible (e.g. as 1D ordinary numpy).
|
|
343
|
+
|
|
344
|
+
"""
|
|
345
|
+
|
|
346
|
+
def __init__(
|
|
347
|
+
self,
|
|
348
|
+
ncol: int,
|
|
349
|
+
nrow: int,
|
|
350
|
+
xinc: float,
|
|
351
|
+
yinc: float,
|
|
352
|
+
xori: Optional[float] = 0.0,
|
|
353
|
+
yori: Optional[float] = 0.0,
|
|
354
|
+
yflip: Optional[int] = 1,
|
|
355
|
+
rotation: Optional[float] = 0.0,
|
|
356
|
+
values: Optional[Union[List[float], float]] = None,
|
|
357
|
+
ilines: Optional[List[float]] = None,
|
|
358
|
+
xlines: Optional[List[float]] = None,
|
|
359
|
+
masked: Optional[bool] = True,
|
|
360
|
+
name: Optional[str] = "unknown",
|
|
361
|
+
filesrc: Optional[str] = None,
|
|
362
|
+
fformat: Optional[str] = None,
|
|
363
|
+
undef: Optional[float] = UNDEF,
|
|
364
|
+
dtype: Union[Type[np.float64], Type[np.float32]] = np.float64,
|
|
365
|
+
):
|
|
366
|
+
"""Instantiating a RegularSurface::
|
|
367
|
+
|
|
368
|
+
vals = np.zeros(30 * 50)
|
|
369
|
+
surf = xtgeo.RegularSurface(
|
|
370
|
+
ncol=30, nrow=50, xori=1234.5, yori=4321.0, xinc=30.0, yinc=50.0,
|
|
371
|
+
rotation=30.0, values=vals, yflip=1,
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
Args:
|
|
375
|
+
ncol: Integer for number of X direction columns.
|
|
376
|
+
nrow: Integer for number of Y direction rows.
|
|
377
|
+
xori: X (East) origon coordinate.
|
|
378
|
+
yori: Y (North) origin coordinate.
|
|
379
|
+
xinc: X increment.
|
|
380
|
+
yinc: Y increment.
|
|
381
|
+
yflip: If 1, the map grid is left-handed (assuming depth downwards),
|
|
382
|
+
otherwise -1 means that Y axis is flipped (right-handed).
|
|
383
|
+
rotation: rotation in degrees, anticlock from X axis between 0, 360.
|
|
384
|
+
values: A scalar (for constant values) or a "array-like" input that has
|
|
385
|
+
ncol * nrow elements. As result, a 2D (masked) numpy array of shape
|
|
386
|
+
(ncol, nrow), C order will be made.
|
|
387
|
+
masked: Indicating if numpy array shall be masked or not. Default is True.
|
|
388
|
+
name: A given name for the surface, default is file name root or
|
|
389
|
+
'unknown' if constructed from scratch.
|
|
390
|
+
|
|
391
|
+
Examples:
|
|
392
|
+
The instance can be made by specification::
|
|
393
|
+
|
|
394
|
+
>>> surface = RegularSurface(
|
|
395
|
+
... ncol=20,
|
|
396
|
+
... nrow=10,
|
|
397
|
+
... xori=2000.0,
|
|
398
|
+
... yori=2000.0,
|
|
399
|
+
... rotation=0.0,
|
|
400
|
+
... xinc=25.0,
|
|
401
|
+
... yinc=25.0,
|
|
402
|
+
... values=np.zeros((20,10))
|
|
403
|
+
... )
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
"""
|
|
407
|
+
logger.info("Start __init__ method for RegularSurface object %s", id(self))
|
|
408
|
+
self._ncol = ncol
|
|
409
|
+
self._nrow = nrow
|
|
410
|
+
self._xori = xori
|
|
411
|
+
self._yori = yori
|
|
412
|
+
self._xinc = xinc
|
|
413
|
+
self._yinc = yinc
|
|
414
|
+
self._rotation = rotation
|
|
415
|
+
self._yflip = yflip
|
|
416
|
+
self._name = name
|
|
417
|
+
|
|
418
|
+
self._undef = undef
|
|
419
|
+
self._undef_limit = UNDEF_LIMIT
|
|
420
|
+
|
|
421
|
+
self._filesrc = filesrc # Name of original input file or stream, if any
|
|
422
|
+
|
|
423
|
+
self._fformat = fformat # current fileformat, useful for load()
|
|
424
|
+
self._metadata = MetaDataRegularSurface()
|
|
425
|
+
|
|
426
|
+
self._values = None
|
|
427
|
+
|
|
428
|
+
if values is None:
|
|
429
|
+
values = np.ma.zeros((self._ncol, self._nrow))
|
|
430
|
+
self._isloaded = False
|
|
431
|
+
else:
|
|
432
|
+
self._isloaded = True
|
|
433
|
+
self._ensure_correct_values(values, force_dtype=dtype)
|
|
434
|
+
|
|
435
|
+
if ilines is None:
|
|
436
|
+
self._ilines = np.array(range(1, self._ncol + 1), dtype=np.int32)
|
|
437
|
+
self._xlines = np.array(range(1, self._nrow + 1), dtype=np.int32)
|
|
438
|
+
else:
|
|
439
|
+
self._ilines = ilines
|
|
440
|
+
self._xlines = xlines
|
|
441
|
+
|
|
442
|
+
self._masked = masked # TODO: check usecase
|
|
443
|
+
self._metadata.required = self
|
|
444
|
+
|
|
445
|
+
@classmethod
|
|
446
|
+
def _read_zmap_ascii(cls, mfile, values):
|
|
447
|
+
mfile = FileWrapper(mfile)
|
|
448
|
+
args = _data_reader_factory(FileFormat.ZMAP_ASCII)(mfile, values=values)
|
|
449
|
+
return cls(**args)
|
|
450
|
+
|
|
451
|
+
@classmethod
|
|
452
|
+
def _read_ijxyz(cls, mfile: FileWrapper, template: RegularSurface | Cube | None):
|
|
453
|
+
mfile = FileWrapper(mfile)
|
|
454
|
+
args = _data_reader_factory(FileFormat.IJXYZ)(mfile, template=template)
|
|
455
|
+
return cls(**args)
|
|
456
|
+
|
|
457
|
+
def __repr__(self):
|
|
458
|
+
"""Magic method __repr__."""
|
|
459
|
+
return (
|
|
460
|
+
f"{self.__class__.__name__} (xori={self._xori!r}, yori={self._yori!r}, "
|
|
461
|
+
f"xinc={self._xinc!r}, yinc={self._yinc!r}, ncol={self._ncol!r}, "
|
|
462
|
+
f"nrow={self._nrow!r}, rotation={self._rotation!r}, yflip={self._yflip!r}, "
|
|
463
|
+
f"masked={self._masked!r}, filesrc={self._filesrc!r}, "
|
|
464
|
+
f"name={self._name!r}, ilines={self.ilines.shape!r}, "
|
|
465
|
+
f"xlines={self.xlines.shape!r}, values={self.values.shape!r}) "
|
|
466
|
+
f"ID={id(self)}."
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
def __str__(self):
|
|
470
|
+
"""Magic method __str__ for user friendly print."""
|
|
471
|
+
return self.describe(flush=False)
|
|
472
|
+
|
|
473
|
+
def __getitem__(self, index):
|
|
474
|
+
"""Magic method."""
|
|
475
|
+
col, row = index
|
|
476
|
+
return self._values[col, row]
|
|
477
|
+
|
|
478
|
+
def __add__(self, other):
|
|
479
|
+
"""Magic method."""
|
|
480
|
+
news = self.copy()
|
|
481
|
+
_regsurf_oper.operations_two(news, other, oper="add")
|
|
482
|
+
|
|
483
|
+
return news
|
|
484
|
+
|
|
485
|
+
def __iadd__(self, other):
|
|
486
|
+
"""Magic method."""
|
|
487
|
+
_regsurf_oper.operations_two(self, other, oper="iadd")
|
|
488
|
+
return self
|
|
489
|
+
|
|
490
|
+
def __sub__(self, other):
|
|
491
|
+
"""Magic method."""
|
|
492
|
+
news = self.copy()
|
|
493
|
+
_regsurf_oper.operations_two(news, other, oper="sub")
|
|
494
|
+
|
|
495
|
+
return news
|
|
496
|
+
|
|
497
|
+
def __isub__(self, other):
|
|
498
|
+
"""Magic method."""
|
|
499
|
+
_regsurf_oper.operations_two(self, other, oper="isub")
|
|
500
|
+
return self
|
|
501
|
+
|
|
502
|
+
def __mul__(self, other):
|
|
503
|
+
"""Magic method."""
|
|
504
|
+
news = self.copy()
|
|
505
|
+
_regsurf_oper.operations_two(news, other, oper="mul")
|
|
506
|
+
|
|
507
|
+
return news
|
|
508
|
+
|
|
509
|
+
def __imul__(self, other):
|
|
510
|
+
"""Magic method."""
|
|
511
|
+
_regsurf_oper.operations_two(self, other, oper="imul")
|
|
512
|
+
return self
|
|
513
|
+
|
|
514
|
+
def __truediv__(self, other):
|
|
515
|
+
"""Magic method."""
|
|
516
|
+
news = self.copy()
|
|
517
|
+
_regsurf_oper.operations_two(news, other, oper="div")
|
|
518
|
+
|
|
519
|
+
return news
|
|
520
|
+
|
|
521
|
+
def __idiv__(self, other):
|
|
522
|
+
"""Magic method."""
|
|
523
|
+
_regsurf_oper.operations_two(self, other, oper="idiv")
|
|
524
|
+
return self
|
|
525
|
+
|
|
526
|
+
# comparison operators, return boolean arrays
|
|
527
|
+
|
|
528
|
+
def __lt__(self, other):
|
|
529
|
+
"""Magic method."""
|
|
530
|
+
return _regsurf_oper.operations_two(self, other, oper="lt")
|
|
531
|
+
|
|
532
|
+
def __gt__(self, other):
|
|
533
|
+
"""Magic method."""
|
|
534
|
+
return _regsurf_oper.operations_two(self, other, oper="gt")
|
|
535
|
+
|
|
536
|
+
def __le__(self, other):
|
|
537
|
+
"""Magic method."""
|
|
538
|
+
return _regsurf_oper.operations_two(self, other, oper="le")
|
|
539
|
+
|
|
540
|
+
def __ge__(self, other):
|
|
541
|
+
"""Magic method."""
|
|
542
|
+
return _regsurf_oper.operations_two(self, other, oper="ge")
|
|
543
|
+
|
|
544
|
+
def __eq__(self, other):
|
|
545
|
+
"""Magic method."""
|
|
546
|
+
return _regsurf_oper.operations_two(self, other, oper="eq")
|
|
547
|
+
|
|
548
|
+
def __ne__(self, other):
|
|
549
|
+
"""Magic method."""
|
|
550
|
+
return _regsurf_oper.operations_two(self, other, oper="ne")
|
|
551
|
+
|
|
552
|
+
# ==================================================================================
|
|
553
|
+
# Class and special methods
|
|
554
|
+
# ==================================================================================
|
|
555
|
+
|
|
556
|
+
@classmethod
|
|
557
|
+
def methods(cls):
|
|
558
|
+
"""Returns the names of the methods in the class.
|
|
559
|
+
|
|
560
|
+
>>> print(RegularSurface.methods())
|
|
561
|
+
METHODS for RegularSurface():
|
|
562
|
+
======================
|
|
563
|
+
__init__
|
|
564
|
+
__repr__
|
|
565
|
+
...
|
|
566
|
+
|
|
567
|
+
"""
|
|
568
|
+
mets = [x for x, y in cls.__dict__.items() if isinstance(y, FunctionType)]
|
|
569
|
+
|
|
570
|
+
txt = "METHODS for RegularSurface():\n======================\n"
|
|
571
|
+
for met in mets:
|
|
572
|
+
txt += str(met) + "\n"
|
|
573
|
+
|
|
574
|
+
return txt
|
|
575
|
+
|
|
576
|
+
# ==================================================================================
|
|
577
|
+
# Properties
|
|
578
|
+
# ==================================================================================
|
|
579
|
+
|
|
580
|
+
@property
|
|
581
|
+
def metadata(self):
|
|
582
|
+
"""Return metadata object instance of type MetaDataRegularSurface."""
|
|
583
|
+
return self._metadata
|
|
584
|
+
|
|
585
|
+
@metadata.setter
|
|
586
|
+
def metadata(self, obj):
|
|
587
|
+
# The current metadata object can be replaced. A bit dangerous so further
|
|
588
|
+
# check must be done to validate. TODO.
|
|
589
|
+
if not isinstance(obj, MetaDataRegularSurface):
|
|
590
|
+
raise ValueError("Input obj not an instance of MetaDataRegularSurface")
|
|
591
|
+
|
|
592
|
+
self._metadata = obj # checking is currently missing! TODO
|
|
593
|
+
|
|
594
|
+
@property
|
|
595
|
+
def ncol(self):
|
|
596
|
+
"""The NCOL (NX or N-Idir) number, as property (read only)."""
|
|
597
|
+
return self._ncol
|
|
598
|
+
|
|
599
|
+
@property
|
|
600
|
+
def nrow(self):
|
|
601
|
+
"""The NROW (NY or N-Jdir) number, as property (read only)."""
|
|
602
|
+
return self._nrow
|
|
603
|
+
|
|
604
|
+
@property
|
|
605
|
+
def dimensions(self):
|
|
606
|
+
"""2-tuple: The surface dimensions as a tuple of 2 integers (read only)."""
|
|
607
|
+
return (self._ncol, self._nrow)
|
|
608
|
+
|
|
609
|
+
@property
|
|
610
|
+
def nactive(self):
|
|
611
|
+
"""Number of active map nodes (read only)."""
|
|
612
|
+
if self._isloaded:
|
|
613
|
+
return self._values.count()
|
|
614
|
+
return None
|
|
615
|
+
|
|
616
|
+
@property
|
|
617
|
+
def rotation(self):
|
|
618
|
+
"""The rotation, anticlock from X axis, in degrees [0..360>."""
|
|
619
|
+
return self._rotation
|
|
620
|
+
|
|
621
|
+
@rotation.setter
|
|
622
|
+
def rotation(self, rota):
|
|
623
|
+
if 0 <= rota < 360:
|
|
624
|
+
self._rotation = rota
|
|
625
|
+
else:
|
|
626
|
+
raise ValueError("Rotation must be in interval [0, 360>")
|
|
627
|
+
|
|
628
|
+
@property
|
|
629
|
+
def xinc(self):
|
|
630
|
+
"""The X increment (or I dir increment)."""
|
|
631
|
+
return self._xinc
|
|
632
|
+
|
|
633
|
+
@property
|
|
634
|
+
def yinc(self):
|
|
635
|
+
"""The Y increment (or I dir increment)."""
|
|
636
|
+
return self._yinc
|
|
637
|
+
|
|
638
|
+
@property
|
|
639
|
+
def yflip(self):
|
|
640
|
+
"""The Y flip (handedness) indicator 1, or -1 (read only).
|
|
641
|
+
|
|
642
|
+
The value 1 (default) means a left-handed system if depth values are
|
|
643
|
+
positive downwards. Assume -1 is rare, but may happen when
|
|
644
|
+
surface is derived from seismic cube.
|
|
645
|
+
"""
|
|
646
|
+
return self._yflip
|
|
647
|
+
|
|
648
|
+
@property
|
|
649
|
+
def xori(self):
|
|
650
|
+
"""The X coordinate origin of the map."""
|
|
651
|
+
return self._xori
|
|
652
|
+
|
|
653
|
+
@xori.setter
|
|
654
|
+
def xori(self, xnew):
|
|
655
|
+
self._xori = xnew
|
|
656
|
+
|
|
657
|
+
@property
|
|
658
|
+
def yori(self):
|
|
659
|
+
"""The Y coordinate origin of the map."""
|
|
660
|
+
return self._yori
|
|
661
|
+
|
|
662
|
+
@yori.setter
|
|
663
|
+
def yori(self, ynew):
|
|
664
|
+
self._yori = ynew
|
|
665
|
+
|
|
666
|
+
@property
|
|
667
|
+
def ilines(self):
|
|
668
|
+
"""The inlines numbering vector (read only)."""
|
|
669
|
+
return self._ilines
|
|
670
|
+
|
|
671
|
+
@ilines.setter
|
|
672
|
+
def ilines(self, values):
|
|
673
|
+
if isinstance(values, np.ndarray) and values.shape[0] == self._ncol:
|
|
674
|
+
self._ilines = values
|
|
675
|
+
|
|
676
|
+
@property
|
|
677
|
+
def xlines(self):
|
|
678
|
+
"""The xlines numbering vector (read only)."""
|
|
679
|
+
return self._xlines
|
|
680
|
+
|
|
681
|
+
@xlines.setter
|
|
682
|
+
def xlines(self, values):
|
|
683
|
+
if isinstance(values, np.ndarray) and values.shape[0] == self._nrow:
|
|
684
|
+
self._xlines = values
|
|
685
|
+
|
|
686
|
+
@property
|
|
687
|
+
def xmin(self):
|
|
688
|
+
"""The minimim X coordinate (read only)."""
|
|
689
|
+
corners = self.get_map_xycorners()
|
|
690
|
+
|
|
691
|
+
xmin = VERYLARGEPOSITIVE
|
|
692
|
+
for corner in corners:
|
|
693
|
+
if corner[0] < xmin:
|
|
694
|
+
xmin = corner[0]
|
|
695
|
+
return xmin
|
|
696
|
+
|
|
697
|
+
@property
|
|
698
|
+
def xmax(self):
|
|
699
|
+
"""The maximum X coordinate (read only)."""
|
|
700
|
+
corners = self.get_map_xycorners()
|
|
701
|
+
|
|
702
|
+
xmax = VERYLARGENEGATIVE
|
|
703
|
+
for corner in corners:
|
|
704
|
+
if corner[0] > xmax:
|
|
705
|
+
xmax = corner[0]
|
|
706
|
+
return xmax
|
|
707
|
+
|
|
708
|
+
@property
|
|
709
|
+
def ymin(self):
|
|
710
|
+
"""The minimim Y coordinate (read only)."""
|
|
711
|
+
corners = self.get_map_xycorners()
|
|
712
|
+
|
|
713
|
+
ymin = VERYLARGEPOSITIVE
|
|
714
|
+
for corner in corners:
|
|
715
|
+
if corner[1] < ymin:
|
|
716
|
+
ymin = corner[1]
|
|
717
|
+
return ymin
|
|
718
|
+
|
|
719
|
+
@property
|
|
720
|
+
def ymax(self):
|
|
721
|
+
"""The maximum Y xoordinate (read only)."""
|
|
722
|
+
corners = self.get_map_xycorners()
|
|
723
|
+
|
|
724
|
+
ymax = VERYLARGENEGATIVE
|
|
725
|
+
for corner in corners:
|
|
726
|
+
if corner[1] > ymax:
|
|
727
|
+
ymax = corner[1]
|
|
728
|
+
return ymax
|
|
729
|
+
|
|
730
|
+
@property
|
|
731
|
+
def dtype(self) -> np.dtype:
|
|
732
|
+
"""Getting the dtype of the values (np.array); float64 or float32"""
|
|
733
|
+
# this is not stored as state varible, but derived from the actual values
|
|
734
|
+
try:
|
|
735
|
+
infer_dtype = self._values.dtype
|
|
736
|
+
except AttributeError:
|
|
737
|
+
infer_dtype = np.float64
|
|
738
|
+
return infer_dtype
|
|
739
|
+
|
|
740
|
+
@dtype.setter
|
|
741
|
+
def dtype(self, wanted_dtype: Union[Type[np.float64], Type[np.float32]]):
|
|
742
|
+
"""Setting the dtype of the values (np.array); float64 or float32"""
|
|
743
|
+
try:
|
|
744
|
+
self._values = self._values.astype(wanted_dtype)
|
|
745
|
+
except TypeError as msg:
|
|
746
|
+
warnings.warn(f"Cannot change dtype: {msg}. Will keep current", UserWarning)
|
|
747
|
+
return
|
|
748
|
+
|
|
749
|
+
@property
|
|
750
|
+
def values(self):
|
|
751
|
+
"""The map values, as 2D masked numpy (float64/32), shape (ncol, nrow).
|
|
752
|
+
|
|
753
|
+
When setting values as a scalar, the current mask will be preserved.
|
|
754
|
+
|
|
755
|
+
When setting values, list-like input (lists, tuples) is also accepted, as
|
|
756
|
+
long as the length is correct and the entries are number-like.
|
|
757
|
+
|
|
758
|
+
In order to specify undefined values, you can specify the ``undef`` attribute
|
|
759
|
+
in the list, or use ``float("nan")``.
|
|
760
|
+
|
|
761
|
+
Example::
|
|
762
|
+
|
|
763
|
+
# list like input where nrow=3 and ncol=5 (15 entries)
|
|
764
|
+
newvalues = list(range(15))
|
|
765
|
+
newvalues[2] = srf.undef
|
|
766
|
+
srf.values = newvalues # here, entry 2 will be undefined
|
|
767
|
+
"""
|
|
768
|
+
return self._values
|
|
769
|
+
|
|
770
|
+
@values.setter
|
|
771
|
+
def values(self, values):
|
|
772
|
+
self._ensure_correct_values(values)
|
|
773
|
+
|
|
774
|
+
@property
|
|
775
|
+
def values1d(self):
|
|
776
|
+
"""(Read only) Map values, as 1D numpy masked, normally a numpy view(?).
|
|
777
|
+
|
|
778
|
+
Example::
|
|
779
|
+
|
|
780
|
+
map = xtgeo.surface_from_file('myfile.gri')
|
|
781
|
+
map.values1d
|
|
782
|
+
"""
|
|
783
|
+
return self.get_values1d(asmasked=True)
|
|
784
|
+
|
|
785
|
+
@property
|
|
786
|
+
def npvalues1d(self):
|
|
787
|
+
"""(Read only) Map values, as 1D numpy (not masked), undef as np.nan.
|
|
788
|
+
|
|
789
|
+
In most cases this will be a copy of the values.
|
|
790
|
+
|
|
791
|
+
Example::
|
|
792
|
+
|
|
793
|
+
>>> import xtgeo
|
|
794
|
+
>>> map = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
795
|
+
>>> values = map.npvalues1d
|
|
796
|
+
>>> mean = np.nanmean(values)
|
|
797
|
+
>>> values[values <= 0] = np.nan
|
|
798
|
+
>>> print(values)
|
|
799
|
+
[nan nan ... nan]
|
|
800
|
+
"""
|
|
801
|
+
return self.get_values1d(asmasked=False, fill_value=np.nan)
|
|
802
|
+
|
|
803
|
+
@property
|
|
804
|
+
def name(self):
|
|
805
|
+
"""A free form name for the surface, to be used in display etc."""
|
|
806
|
+
return self._name
|
|
807
|
+
|
|
808
|
+
@name.setter
|
|
809
|
+
def name(self, newname):
|
|
810
|
+
if isinstance(newname, str):
|
|
811
|
+
self._name = newname
|
|
812
|
+
|
|
813
|
+
@property
|
|
814
|
+
def undef(self):
|
|
815
|
+
"""Returns the undef map value (read only)."""
|
|
816
|
+
return self._undef
|
|
817
|
+
|
|
818
|
+
@property
|
|
819
|
+
def undef_limit(self):
|
|
820
|
+
"""Returns the undef_limit map value (read only)."""
|
|
821
|
+
return self._undef_limit
|
|
822
|
+
|
|
823
|
+
@property
|
|
824
|
+
def filesrc(self):
|
|
825
|
+
"""Gives the name of the file source (if any)."""
|
|
826
|
+
return self._filesrc
|
|
827
|
+
|
|
828
|
+
@filesrc.setter
|
|
829
|
+
def filesrc(self, name):
|
|
830
|
+
self._filesrc = name # checking is currently missing
|
|
831
|
+
|
|
832
|
+
# ==================================================================================
|
|
833
|
+
# Describe, import and export
|
|
834
|
+
# ==================================================================================
|
|
835
|
+
|
|
836
|
+
def generate_hash(self, hashmethod="md5"):
|
|
837
|
+
"""Return a unique hash ID for current instance.
|
|
838
|
+
|
|
839
|
+
See :meth:`~xtgeo.common.sys.generic_hash()` for documentation.
|
|
840
|
+
|
|
841
|
+
.. versionadded:: 2.14
|
|
842
|
+
"""
|
|
843
|
+
required = (
|
|
844
|
+
"ncol",
|
|
845
|
+
"nrow",
|
|
846
|
+
"xori",
|
|
847
|
+
"yori",
|
|
848
|
+
"xinc",
|
|
849
|
+
"yinc",
|
|
850
|
+
"yflip",
|
|
851
|
+
"rotation",
|
|
852
|
+
)
|
|
853
|
+
gid = ""
|
|
854
|
+
for req in required:
|
|
855
|
+
gid += f"{getattr(self, '_' + req)}"
|
|
856
|
+
# Ignore the mask
|
|
857
|
+
gid += self._values.data.tobytes().hex()
|
|
858
|
+
|
|
859
|
+
return generic_hash(gid, hashmethod=hashmethod)
|
|
860
|
+
|
|
861
|
+
def describe(self, flush=True):
|
|
862
|
+
"""Describe an instance by printing to stdout."""
|
|
863
|
+
#
|
|
864
|
+
dsc = XTGDescription()
|
|
865
|
+
dsc.title("Description of RegularSurface instance")
|
|
866
|
+
dsc.txt("Object ID", id(self))
|
|
867
|
+
dsc.txt("File source", self._filesrc)
|
|
868
|
+
dsc.txt("Shape: NCOL, NROW", self.ncol, self.nrow)
|
|
869
|
+
dsc.txt("Active cells vs total", self.nactive, self.nrow * self.ncol)
|
|
870
|
+
dsc.txt("Origins XORI, YORI", self.xori, self.yori)
|
|
871
|
+
dsc.txt("Increments XINC YINC", self.xinc, self.yinc)
|
|
872
|
+
dsc.txt("Rotation (anti-clock from X)", self.rotation)
|
|
873
|
+
dsc.txt("YFLIP flag", self._yflip)
|
|
874
|
+
np.set_printoptions(threshold=16)
|
|
875
|
+
dsc.txt("Inlines vector", self._ilines)
|
|
876
|
+
dsc.txt("Xlines vector", self._xlines)
|
|
877
|
+
np.set_printoptions(threshold=1000)
|
|
878
|
+
if self._isloaded:
|
|
879
|
+
dsc.txt("Values", self._values.reshape(-1), self._values.dtype)
|
|
880
|
+
dsc.txt(
|
|
881
|
+
"Values: mean, stdev, minimum, maximum",
|
|
882
|
+
self.values.mean(),
|
|
883
|
+
self.values.std(),
|
|
884
|
+
self.values.min(),
|
|
885
|
+
self.values.max(),
|
|
886
|
+
)
|
|
887
|
+
msize = float(self.values.size * 8) / (1024 * 1024 * 1024)
|
|
888
|
+
dsc.txt("Minimum memory usage of array (GB)", msize)
|
|
889
|
+
else:
|
|
890
|
+
dsc.txt("Values:", "Not loaded")
|
|
891
|
+
|
|
892
|
+
if flush:
|
|
893
|
+
dsc.flush()
|
|
894
|
+
return None
|
|
895
|
+
|
|
896
|
+
return dsc.astext()
|
|
897
|
+
|
|
898
|
+
@classmethod
|
|
899
|
+
def _read_file(
|
|
900
|
+
cls,
|
|
901
|
+
mfile: Union[str, pathlib.Path, io.BytesIO],
|
|
902
|
+
fformat: Optional[str] = None,
|
|
903
|
+
load_values: bool = True,
|
|
904
|
+
**kwargs,
|
|
905
|
+
):
|
|
906
|
+
"""Import surface (regular map) from file.
|
|
907
|
+
|
|
908
|
+
Note that the ``fformat=None`` or ``guess`` option will guess format by
|
|
909
|
+
looking at the file or stream signature or file extension.
|
|
910
|
+
For the signature, the first bytes are scanned for 'patterns'. If that
|
|
911
|
+
does not work (and input is not a memory stream), it will try to use
|
|
912
|
+
file extension where e.g. "gri" will assume irap_binary and "fgr"
|
|
913
|
+
assume Irap Ascii. If file extension is missing, Irap binary is assumed.
|
|
914
|
+
|
|
915
|
+
The ``ijxyz`` format is the typical seismic format, on the form
|
|
916
|
+
(ILINE, XLINE, X, Y, VALUE) as a table of points. Map values are
|
|
917
|
+
estimated from the given values, or by using an existing map or
|
|
918
|
+
cube as template, and match by ILINE/XLINE numbering.
|
|
919
|
+
|
|
920
|
+
BytesIO input is supported for Irap binary, Irap Ascii, ZMAP ascii.
|
|
921
|
+
|
|
922
|
+
Args:
|
|
923
|
+
mfile: File-like or memory stream instance.
|
|
924
|
+
fformat: File format, None/guess/irap_binary/irap_ascii/ijxyz
|
|
925
|
+
is currently supported. If None or guess, the file 'signature' is
|
|
926
|
+
used to guess format first, then file extension.
|
|
927
|
+
load_values: If True (default), then full array is read, if False
|
|
928
|
+
only metadata will be read. Valid for Irap binary only. This allows
|
|
929
|
+
lazy loading in e.g. ensembles.
|
|
930
|
+
kwargs: some readers allow additonal options
|
|
931
|
+
|
|
932
|
+
Keyword Args:
|
|
933
|
+
template: Only valid if ``ijxyz`` format, where an
|
|
934
|
+
existing Cube or RegularSurface instance is applied to
|
|
935
|
+
get correct topology.
|
|
936
|
+
engine: Deprecated keyword with no function, will be removed in version 5.
|
|
937
|
+
|
|
938
|
+
Returns:
|
|
939
|
+
Object instance.
|
|
940
|
+
|
|
941
|
+
Example::
|
|
942
|
+
|
|
943
|
+
>>> surf = RegularSurface._read_file(surface_dir + "/topreek_rota.gri")
|
|
944
|
+
|
|
945
|
+
.. versionadded:: 2.14
|
|
946
|
+
|
|
947
|
+
"""
|
|
948
|
+
mfile = FileWrapper(mfile)
|
|
949
|
+
mfile.check_file(raiseerror=ValueError)
|
|
950
|
+
fmt = mfile.fileformat(fformat)
|
|
951
|
+
|
|
952
|
+
new_kwargs = _data_reader_factory(fmt)(mfile, values=load_values, **kwargs)
|
|
953
|
+
new_kwargs["filesrc"] = mfile.file
|
|
954
|
+
new_kwargs["fformat"] = fmt
|
|
955
|
+
new_kwargs["dtype"] = kwargs.get("dtype", np.float64)
|
|
956
|
+
return cls(**new_kwargs)
|
|
957
|
+
|
|
958
|
+
def load_values(self):
|
|
959
|
+
"""Import surface values in cases where metadata only is loaded.
|
|
960
|
+
|
|
961
|
+
Currently, only Irap binary format is supported.
|
|
962
|
+
|
|
963
|
+
Example::
|
|
964
|
+
|
|
965
|
+
surfs = []
|
|
966
|
+
for i in range(1000):
|
|
967
|
+
surfs.append(xtgeo.surface_from_file(f"myfile{i}.gri", values=False))
|
|
968
|
+
|
|
969
|
+
# load values in number 88:
|
|
970
|
+
surfs[88].load_values()
|
|
971
|
+
|
|
972
|
+
.. versionadded:: 2.1
|
|
973
|
+
"""
|
|
974
|
+
|
|
975
|
+
if not self._isloaded:
|
|
976
|
+
if self.filesrc is None:
|
|
977
|
+
raise ValueError(
|
|
978
|
+
"Can only load values into object initialised from file"
|
|
979
|
+
)
|
|
980
|
+
|
|
981
|
+
with warnings.catch_warnings():
|
|
982
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
983
|
+
mfile = FileWrapper(self.filesrc)
|
|
984
|
+
kwargs = _data_reader_factory(self._fformat)(mfile, values=True)
|
|
985
|
+
self.values = kwargs.get("values", self._values)
|
|
986
|
+
|
|
987
|
+
self._isloaded = True
|
|
988
|
+
|
|
989
|
+
def to_file(
|
|
990
|
+
self,
|
|
991
|
+
mfile: Union[str, pathlib.Path, io.BytesIO],
|
|
992
|
+
fformat: Optional[str] = "irap_binary",
|
|
993
|
+
pmd_dataunits: Optional[Tuple[int, int]] = (15, 10),
|
|
994
|
+
engine: Optional[str] = None,
|
|
995
|
+
error_if_near_empty: bool = False,
|
|
996
|
+
):
|
|
997
|
+
"""Export a surface (map) to file.
|
|
998
|
+
|
|
999
|
+
Note, for zmap_ascii and storm_binary an unrotation will be done
|
|
1000
|
+
automatically. The sampling will be somewhat finer than the
|
|
1001
|
+
original map in order to prevent aliasing. See :func:`unrotate`.
|
|
1002
|
+
|
|
1003
|
+
Args:
|
|
1004
|
+
mfile: Name of file,
|
|
1005
|
+
Path instance or IOBytestream instance. An alias can be e.g.
|
|
1006
|
+
"%md5sum%" or "%fmu-v1%" with string or Path() input.
|
|
1007
|
+
fformat: File format, irap_binary/irap_ascii/zmap_ascii/
|
|
1008
|
+
storm_binary/ijxyz/petromod/xtg*. Default is irap_binary.
|
|
1009
|
+
pmd_dataunits: A tuple of length 2 for petromod format,
|
|
1010
|
+
spesifying metadata for units (DataUnitDistance, DataUnitZ).
|
|
1011
|
+
engine: This was mainly a developer setting! The 'engine' is now deprecated.
|
|
1012
|
+
error_if_near_empty: Default is False. If True, raise a RuntimeError if
|
|
1013
|
+
number of map nodes is less than 4. Otherwise, if False and number of
|
|
1014
|
+
nodes are less than 4, a UserWarning will be given.
|
|
1015
|
+
|
|
1016
|
+
Returns:
|
|
1017
|
+
ofile (pathlib.Path): The actual file instance, or None if io.Bytestream
|
|
1018
|
+
|
|
1019
|
+
Examples::
|
|
1020
|
+
|
|
1021
|
+
>>> # read and write to ordinary file
|
|
1022
|
+
>>> surf = xtgeo.surface_from_file(
|
|
1023
|
+
... surface_dir + '/topreek_rota.fgr',
|
|
1024
|
+
... fformat = 'irap_ascii'
|
|
1025
|
+
... )
|
|
1026
|
+
>>> surf.values = surf.values + 300
|
|
1027
|
+
>>> filename = surf.to_file(
|
|
1028
|
+
... outdir + '/topreek_rota300.fgr',
|
|
1029
|
+
... fformat = 'irap_ascii'
|
|
1030
|
+
... )
|
|
1031
|
+
|
|
1032
|
+
>>> # writing to io.BytesIO:
|
|
1033
|
+
>>> stream = io.BytesIO()
|
|
1034
|
+
>>> surf.to_file(stream, fformat="irap_binary")
|
|
1035
|
+
|
|
1036
|
+
>>> # read from memory stream:
|
|
1037
|
+
>>> _ = stream.seek(0)
|
|
1038
|
+
>>> newsurf = xtgeo.surface_from_file(stream, fformat = 'irap_binary')
|
|
1039
|
+
|
|
1040
|
+
.. versionchanged:: 2.5 Added support for BytesIO
|
|
1041
|
+
.. versionchanged:: 2.13 Improved support for BytesIO
|
|
1042
|
+
.. versionchanged:: 2.14 Support for alias file name and return value
|
|
1043
|
+
.. versionchanged:: 3.8 Add key ``error_if_near_empty``
|
|
1044
|
+
.. versionchanged:: 4.6 The ``engine`` keyword (for developers) is deprecated
|
|
1045
|
+
and will be removed in version 5
|
|
1046
|
+
"""
|
|
1047
|
+
if engine:
|
|
1048
|
+
warnings.warn(
|
|
1049
|
+
"The 'engine' keyword is deprecated and will be removed in XTGeo 5"
|
|
1050
|
+
"(Note that this key was intended as a developer setting.)"
|
|
1051
|
+
"Please remove this key from your code.",
|
|
1052
|
+
DeprecationWarning,
|
|
1053
|
+
stacklevel=2,
|
|
1054
|
+
)
|
|
1055
|
+
|
|
1056
|
+
logger.info("Export RegularSurface to file or memstream...")
|
|
1057
|
+
if self.nactive is None or self.nactive < 4:
|
|
1058
|
+
msg = (
|
|
1059
|
+
f"Number of maps nodes are {self.nactive}. Exporting regular "
|
|
1060
|
+
"surfaces with fewer than 4 nodes will not provide any "
|
|
1061
|
+
"usable result. The map may also be not loaded if nodes are None."
|
|
1062
|
+
)
|
|
1063
|
+
|
|
1064
|
+
if error_if_near_empty:
|
|
1065
|
+
raise RuntimeError(msg)
|
|
1066
|
+
warnings.warn(msg, UserWarning)
|
|
1067
|
+
|
|
1068
|
+
mfile = FileWrapper(mfile, mode="wb", obj=self)
|
|
1069
|
+
mfile.check_folder(raiseerror=OSError)
|
|
1070
|
+
|
|
1071
|
+
if fformat in FileFormat.IRAP_ASCII.value:
|
|
1072
|
+
_regsurf_export.export_irap_ascii(self, mfile)
|
|
1073
|
+
|
|
1074
|
+
elif fformat in FileFormat.IRAP_BINARY.value:
|
|
1075
|
+
_regsurf_export.export_irap_binary(self, mfile)
|
|
1076
|
+
|
|
1077
|
+
elif fformat in FileFormat.ZMAP_ASCII.value:
|
|
1078
|
+
_regsurf_export.export_zmap_ascii(self, mfile)
|
|
1079
|
+
|
|
1080
|
+
elif fformat in FileFormat.STORM.value:
|
|
1081
|
+
_regsurf_export.export_storm_binary(self, mfile)
|
|
1082
|
+
|
|
1083
|
+
elif fformat in FileFormat.PETROMOD.value:
|
|
1084
|
+
_regsurf_export.export_petromod_binary(self, mfile, pmd_dataunits)
|
|
1085
|
+
|
|
1086
|
+
elif fformat in FileFormat.IJXYZ.value:
|
|
1087
|
+
_regsurf_export.export_ijxyz_ascii(self, mfile)
|
|
1088
|
+
|
|
1089
|
+
elif fformat == "xtgregsurf":
|
|
1090
|
+
_regsurf_export.export_xtgregsurf(self, mfile)
|
|
1091
|
+
|
|
1092
|
+
else:
|
|
1093
|
+
extensions = FileFormat.extensions_string(
|
|
1094
|
+
[
|
|
1095
|
+
FileFormat.IRAP_BINARY,
|
|
1096
|
+
FileFormat.IRAP_ASCII,
|
|
1097
|
+
FileFormat.IJXYZ,
|
|
1098
|
+
FileFormat.PETROMOD,
|
|
1099
|
+
FileFormat.ZMAP_ASCII,
|
|
1100
|
+
FileFormat.XTG,
|
|
1101
|
+
FileFormat.HDF,
|
|
1102
|
+
]
|
|
1103
|
+
)
|
|
1104
|
+
raise InvalidFileFormatError(
|
|
1105
|
+
f"File format {fformat} is invalid for type RegularSurface. "
|
|
1106
|
+
f"Supported formats are {extensions}."
|
|
1107
|
+
)
|
|
1108
|
+
|
|
1109
|
+
logger.info("Export RegularSurface to file or memstream... done")
|
|
1110
|
+
|
|
1111
|
+
if mfile.memstream:
|
|
1112
|
+
return None
|
|
1113
|
+
return mfile.file
|
|
1114
|
+
|
|
1115
|
+
def to_hdf(
|
|
1116
|
+
self,
|
|
1117
|
+
mfile: Union[str, pathlib.Path, io.BytesIO],
|
|
1118
|
+
compression: Optional[str] = "lzf",
|
|
1119
|
+
) -> pathlib.Path:
|
|
1120
|
+
"""Export a surface (map) with metadata to a HDF5 file.
|
|
1121
|
+
|
|
1122
|
+
Warning:
|
|
1123
|
+
This implementation is currently experimental and only recommended
|
|
1124
|
+
for testing.
|
|
1125
|
+
|
|
1126
|
+
The file extension shall be '.hdf'
|
|
1127
|
+
|
|
1128
|
+
Args:
|
|
1129
|
+
mfile: Name of file, Path instance or BytesIO instance. An alias can
|
|
1130
|
+
be e.g. ``$md5sum.hdf``, ``$fmu-v1.hdf`` with string or Path() input.
|
|
1131
|
+
compression: Compression method, None, lzf (default), blosc
|
|
1132
|
+
|
|
1133
|
+
Returns:
|
|
1134
|
+
pathlib.Path: The actual file instance, or None if io.Bytestream
|
|
1135
|
+
|
|
1136
|
+
Example:
|
|
1137
|
+
>>> import xtgeo
|
|
1138
|
+
>>> surf = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
1139
|
+
>>> filepath = surf.to_hdf(outdir + "/topreek_rota.hdf")
|
|
1140
|
+
|
|
1141
|
+
.. versionadded:: 2.14
|
|
1142
|
+
|
|
1143
|
+
"""
|
|
1144
|
+
# developing, in prep and experimental!
|
|
1145
|
+
mfile = FileWrapper(mfile, mode="wb", obj=self)
|
|
1146
|
+
|
|
1147
|
+
mfile.check_folder(raiseerror=OSError)
|
|
1148
|
+
|
|
1149
|
+
_regsurf_export.export_hdf5_regsurf(self, mfile, compression=compression)
|
|
1150
|
+
return mfile.file
|
|
1151
|
+
|
|
1152
|
+
@classmethod
|
|
1153
|
+
def _read_roxar(
|
|
1154
|
+
cls,
|
|
1155
|
+
project,
|
|
1156
|
+
name,
|
|
1157
|
+
category,
|
|
1158
|
+
stype="horizons",
|
|
1159
|
+
realisation=0,
|
|
1160
|
+
dtype=np.float64,
|
|
1161
|
+
): # pragma: no cover
|
|
1162
|
+
"""Load a surface from a Roxar RMS project.
|
|
1163
|
+
|
|
1164
|
+
The import from the RMS project can be done either within the project
|
|
1165
|
+
or outside the project.
|
|
1166
|
+
|
|
1167
|
+
Note that a shortform to::
|
|
1168
|
+
|
|
1169
|
+
import xtgeo
|
|
1170
|
+
mysurf = xtgeo.surface_from_roxar(project, 'name', 'category')
|
|
1171
|
+
|
|
1172
|
+
Note also that horizon/zone name and category must exists in advance,
|
|
1173
|
+
otherwise an Exception will be raised.
|
|
1174
|
+
|
|
1175
|
+
Args:
|
|
1176
|
+
project (str or special): Name of project (as folder) if
|
|
1177
|
+
outside RMS, og just use the magic project word if within RMS.
|
|
1178
|
+
name (str): Name of surface/map
|
|
1179
|
+
category (str): For horizons/zones or clipboard/general2d_data: for
|
|
1180
|
+
example 'DS_extracted'
|
|
1181
|
+
stype (str): RMS folder type, 'horizons' (default), 'zones' or 'clipboard'
|
|
1182
|
+
realisation (int): Realisation number, default is 0
|
|
1183
|
+
dtype: For supporting conversion to 32 bit float for the numpy; default
|
|
1184
|
+
is 64 bit
|
|
1185
|
+
|
|
1186
|
+
"""
|
|
1187
|
+
kwargs = _regsurf_roxapi.import_horizon_roxapi(
|
|
1188
|
+
project, name, category, stype, realisation
|
|
1189
|
+
)
|
|
1190
|
+
kwargs["dtype"] = dtype # eventual dtype change will be done in __init__
|
|
1191
|
+
|
|
1192
|
+
return cls(**kwargs)
|
|
1193
|
+
|
|
1194
|
+
def to_roxar(
|
|
1195
|
+
self, project, name, category, stype="horizons", realisation=0
|
|
1196
|
+
): # pragma: no cover
|
|
1197
|
+
"""Store (export) a regular surface to a Roxar RMS project.
|
|
1198
|
+
|
|
1199
|
+
The export to the RMS project can be done either within the project
|
|
1200
|
+
or outside the project. The storing is done to the Horizons or the
|
|
1201
|
+
Zones folder in RMS.
|
|
1202
|
+
|
|
1203
|
+
Note:
|
|
1204
|
+
The horizon or zone name and category must exists in advance,
|
|
1205
|
+
otherwise an Exception will be raised.
|
|
1206
|
+
|
|
1207
|
+
When project is file path (direct access, outside RMS) then
|
|
1208
|
+
``to_roxar()`` will implicitly do a project save. Otherwise, the project
|
|
1209
|
+
will not be saved until the user do an explicit project save action.
|
|
1210
|
+
|
|
1211
|
+
Args:
|
|
1212
|
+
project (str or special): Name of project (as folder) if
|
|
1213
|
+
outside RMS, og just use the magic project word if within RMS.
|
|
1214
|
+
name (str): Name of surface/map
|
|
1215
|
+
category (str): Required for horizons/zones: e.g. 'DS_extracted'. For
|
|
1216
|
+
clipboard/general2d_data is reperesent the folder(s), where "" or None
|
|
1217
|
+
means no folder, while e.g. "myfolder/subfolder" means that folders
|
|
1218
|
+
myfolder/subfolder will be created if not already present. For
|
|
1219
|
+
stype = 'trends', the category will not be applied
|
|
1220
|
+
stype (str): RMS folder type, 'horizons' (default), 'zones', 'clipboard'
|
|
1221
|
+
'general2d_data', 'trends'
|
|
1222
|
+
realisation (int): Realisation number, default is 0
|
|
1223
|
+
|
|
1224
|
+
Raises:
|
|
1225
|
+
ValueError: If name or category does not exist in the project
|
|
1226
|
+
|
|
1227
|
+
Example:
|
|
1228
|
+
Here the from_roxar method is used to initiate the object
|
|
1229
|
+
directly::
|
|
1230
|
+
|
|
1231
|
+
import xtgeo
|
|
1232
|
+
topupperreek = xtgeo.surface_from_roxar(project, 'TopUpperReek',
|
|
1233
|
+
'DS_extracted')
|
|
1234
|
+
topupperreek.values += 200
|
|
1235
|
+
|
|
1236
|
+
# export to file:
|
|
1237
|
+
topupperreek.to_file('topupperreek.gri')
|
|
1238
|
+
|
|
1239
|
+
# store in project
|
|
1240
|
+
topupperreek.to_roxar(project, 'TopUpperReek', 'DS_something')
|
|
1241
|
+
|
|
1242
|
+
Note::
|
|
1243
|
+
|
|
1244
|
+
When dealing with surfaces to and from ``stype="trends"``, the surface must
|
|
1245
|
+
exist in advance, i.e. the Roxar API do not allow creating new surfaces.
|
|
1246
|
+
Actually trends are read only, but a workaround using ``load()`` in Roxar
|
|
1247
|
+
API makes it possible to overwrite existing surface trends. In addition,
|
|
1248
|
+
``realisation`` is not applied in trends.
|
|
1249
|
+
|
|
1250
|
+
|
|
1251
|
+
.. versionadded:: 2.1 clipboard support
|
|
1252
|
+
.. versionadded:: 2.19 general2d_data and trends support
|
|
1253
|
+
|
|
1254
|
+
"""
|
|
1255
|
+
_regsurf_roxapi.export_horizon_roxapi(
|
|
1256
|
+
self, project, name, category, stype, realisation
|
|
1257
|
+
)
|
|
1258
|
+
|
|
1259
|
+
@classmethod
|
|
1260
|
+
def _read_cube(cls, cube, zlevel):
|
|
1261
|
+
"""Make a constant surface from a Cube, at a given time/depth level.
|
|
1262
|
+
|
|
1263
|
+
The surface instance will have exactly the same origins and increments
|
|
1264
|
+
as the cube.
|
|
1265
|
+
|
|
1266
|
+
Args:
|
|
1267
|
+
cube (Cube): XTGeo Cube instance
|
|
1268
|
+
zlevel (float): Depth or Time (or whatever) value of the surface
|
|
1269
|
+
|
|
1270
|
+
Returns:
|
|
1271
|
+
Object instance updated
|
|
1272
|
+
|
|
1273
|
+
Example:
|
|
1274
|
+
Here the from_roxar method is used to initiate the object
|
|
1275
|
+
directly::
|
|
1276
|
+
|
|
1277
|
+
>>> mycube = xtgeo.cube_from_file(cube_dir + "/ib_test_cube2.segy")
|
|
1278
|
+
>>> mymap = RegularSurface._read_cube(mycube, 2700)
|
|
1279
|
+
|
|
1280
|
+
"""
|
|
1281
|
+
props = [
|
|
1282
|
+
"ncol",
|
|
1283
|
+
"nrow",
|
|
1284
|
+
"xori",
|
|
1285
|
+
"yori",
|
|
1286
|
+
"xinc",
|
|
1287
|
+
"yinc",
|
|
1288
|
+
"rotation",
|
|
1289
|
+
"ilines",
|
|
1290
|
+
"xlines",
|
|
1291
|
+
"yflip",
|
|
1292
|
+
]
|
|
1293
|
+
|
|
1294
|
+
input_dict = {key: deepcopy(getattr(cube, key)) for key in props}
|
|
1295
|
+
|
|
1296
|
+
input_dict["values"] = ma.array(
|
|
1297
|
+
np.full((input_dict["ncol"], input_dict["nrow"]), zlevel, dtype=np.float64)
|
|
1298
|
+
)
|
|
1299
|
+
return cls(**input_dict)
|
|
1300
|
+
|
|
1301
|
+
@classmethod
|
|
1302
|
+
def _read_grid3d(
|
|
1303
|
+
cls,
|
|
1304
|
+
grid: Grid,
|
|
1305
|
+
template: RegularSurface | str | None = None,
|
|
1306
|
+
where: str | int = "top",
|
|
1307
|
+
property: str | GridProperty = "depth",
|
|
1308
|
+
rfactor: int = 1,
|
|
1309
|
+
index_position: str = "center",
|
|
1310
|
+
):
|
|
1311
|
+
"""Private class method to extract a surface from a 3D grid."""
|
|
1312
|
+
args = _regsurf_grid3d.from_grid3d(
|
|
1313
|
+
grid, template, where, property, rfactor, index_position
|
|
1314
|
+
)
|
|
1315
|
+
return cls(**args)
|
|
1316
|
+
|
|
1317
|
+
def copy(self):
|
|
1318
|
+
"""Deep copy of a RegularSurface object to another instance.
|
|
1319
|
+
|
|
1320
|
+
Example::
|
|
1321
|
+
|
|
1322
|
+
>>> mymap = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
1323
|
+
>>> mymapcopy = mymap.copy()
|
|
1324
|
+
|
|
1325
|
+
"""
|
|
1326
|
+
|
|
1327
|
+
xsurf = RegularSurface(
|
|
1328
|
+
ncol=self.ncol,
|
|
1329
|
+
nrow=self.nrow,
|
|
1330
|
+
xinc=self.xinc,
|
|
1331
|
+
yinc=self.yinc,
|
|
1332
|
+
xori=self.xori,
|
|
1333
|
+
yori=self.yori,
|
|
1334
|
+
rotation=self.rotation,
|
|
1335
|
+
yflip=self.yflip,
|
|
1336
|
+
)
|
|
1337
|
+
|
|
1338
|
+
xsurf._values = self._values.copy()
|
|
1339
|
+
xsurf._isloaded = self._isloaded
|
|
1340
|
+
|
|
1341
|
+
xsurf.ilines = self._ilines.copy()
|
|
1342
|
+
xsurf.xlines = self._xlines.copy()
|
|
1343
|
+
xsurf.filesrc = self._filesrc
|
|
1344
|
+
xsurf.metadata.required = xsurf
|
|
1345
|
+
|
|
1346
|
+
return xsurf
|
|
1347
|
+
|
|
1348
|
+
def get_values1d(
|
|
1349
|
+
self, order="C", asmasked=False, fill_value=UNDEF, activeonly=False
|
|
1350
|
+
):
|
|
1351
|
+
"""Get a 1D numpy or masked array of the map values.
|
|
1352
|
+
|
|
1353
|
+
Args:
|
|
1354
|
+
order (str): Flatteting is in C (default) or F order
|
|
1355
|
+
asmasked (bool): If true, return as MaskedArray, other as standard
|
|
1356
|
+
numpy ndarray with undef as np.nan or fill_value
|
|
1357
|
+
fill_value (str): Relevent only if asmasked is False, this
|
|
1358
|
+
will be the value of undef entries
|
|
1359
|
+
activeonly (bool): If True, only active cells. Keys 'asmasked' and
|
|
1360
|
+
'fill_value' are not revelant.
|
|
1361
|
+
|
|
1362
|
+
Returns:
|
|
1363
|
+
A numpy 1D array or MaskedArray
|
|
1364
|
+
|
|
1365
|
+
"""
|
|
1366
|
+
val = self.values.copy()
|
|
1367
|
+
|
|
1368
|
+
if order == "F":
|
|
1369
|
+
val = ma.array(val.data, mask=val.mask, order="F")
|
|
1370
|
+
|
|
1371
|
+
val = val.ravel(order=order)
|
|
1372
|
+
|
|
1373
|
+
if activeonly:
|
|
1374
|
+
val = val[~val.mask]
|
|
1375
|
+
|
|
1376
|
+
if not asmasked and not activeonly:
|
|
1377
|
+
val = ma.filled(val, fill_value=fill_value)
|
|
1378
|
+
|
|
1379
|
+
return val
|
|
1380
|
+
|
|
1381
|
+
def set_values1d(self, val, order="C"):
|
|
1382
|
+
"""Update the values attribute based on a 1D input, multiple options.
|
|
1383
|
+
|
|
1384
|
+
If values are np.nan or values are > UNDEF_LIMIT, they will be
|
|
1385
|
+
masked.
|
|
1386
|
+
|
|
1387
|
+
Args:
|
|
1388
|
+
val (list-like): Set values as a 1D array
|
|
1389
|
+
order (str): Input is C (default) or F order
|
|
1390
|
+
"""
|
|
1391
|
+
if order == "F":
|
|
1392
|
+
val = np.copy(val, order="C")
|
|
1393
|
+
|
|
1394
|
+
val = val.reshape((self.ncol, self.nrow))
|
|
1395
|
+
|
|
1396
|
+
if not isinstance(val, ma.MaskedArray):
|
|
1397
|
+
val = ma.array(val)
|
|
1398
|
+
|
|
1399
|
+
val = ma.masked_greater(val, self.undef_limit)
|
|
1400
|
+
val = ma.masked_invalid(val)
|
|
1401
|
+
|
|
1402
|
+
self.values = val
|
|
1403
|
+
|
|
1404
|
+
def get_rotation(self):
|
|
1405
|
+
"""Returns the surface roation, in degrees, from X, anti-clock."""
|
|
1406
|
+
return self._rotation
|
|
1407
|
+
|
|
1408
|
+
def get_nx(self):
|
|
1409
|
+
"""Same as ncol (nx) (for backward compatibility)."""
|
|
1410
|
+
return self._ncol
|
|
1411
|
+
|
|
1412
|
+
def get_ny(self):
|
|
1413
|
+
"""Same as nrow (ny) (for backward compatibility)."""
|
|
1414
|
+
return self._nrow
|
|
1415
|
+
|
|
1416
|
+
def get_xori(self):
|
|
1417
|
+
"""Same as property xori (for backward compatibility)."""
|
|
1418
|
+
return self._xori
|
|
1419
|
+
|
|
1420
|
+
def get_yori(self):
|
|
1421
|
+
"""Same as property yori (for backward compatibility)."""
|
|
1422
|
+
return self._yori
|
|
1423
|
+
|
|
1424
|
+
def get_xinc(self):
|
|
1425
|
+
"""Same as property xinc (for backward compatibility)."""
|
|
1426
|
+
return self._xinc
|
|
1427
|
+
|
|
1428
|
+
def get_yinc(self):
|
|
1429
|
+
"""Same as property yinc (for backward compatibility)."""
|
|
1430
|
+
return self._yinc
|
|
1431
|
+
|
|
1432
|
+
def similarity_index(self, other):
|
|
1433
|
+
"""Report the degree of similarity between two maps, by comparing mean.
|
|
1434
|
+
|
|
1435
|
+
The method computes the average per surface, and the similarity
|
|
1436
|
+
is difference in mean divided on mean of self. I.e. values close
|
|
1437
|
+
to 0.0 mean small difference.
|
|
1438
|
+
|
|
1439
|
+
Args:
|
|
1440
|
+
other (surface object): The other surface to compare with
|
|
1441
|
+
|
|
1442
|
+
"""
|
|
1443
|
+
ovalues = other.values
|
|
1444
|
+
svalues = self.values
|
|
1445
|
+
|
|
1446
|
+
diff = math.pow(svalues.mean() - ovalues.mean(), 2)
|
|
1447
|
+
diff = math.sqrt(diff)
|
|
1448
|
+
|
|
1449
|
+
try:
|
|
1450
|
+
diff = diff / svalues.mean()
|
|
1451
|
+
except ZeroDivisionError:
|
|
1452
|
+
diff = -999
|
|
1453
|
+
|
|
1454
|
+
return diff
|
|
1455
|
+
|
|
1456
|
+
def compare_topology(self, other: RegularSurface, strict: bool = True) -> bool:
|
|
1457
|
+
"""Check that two object has the same topology, i.e. map definitions.
|
|
1458
|
+
|
|
1459
|
+
Map definitions such as origin, dimensions, number of defined cells...
|
|
1460
|
+
|
|
1461
|
+
Args:
|
|
1462
|
+
other: The other surface to compare with
|
|
1463
|
+
strict (bool): If false, the masks are not compared
|
|
1464
|
+
|
|
1465
|
+
Returns:
|
|
1466
|
+
True of same topology, False if not
|
|
1467
|
+
"""
|
|
1468
|
+
tstatus = True
|
|
1469
|
+
|
|
1470
|
+
# consider refactor to getattr() instead!
|
|
1471
|
+
chklist = {
|
|
1472
|
+
"_ncol",
|
|
1473
|
+
"_nrow",
|
|
1474
|
+
"_xori",
|
|
1475
|
+
"_yori",
|
|
1476
|
+
"_xinc",
|
|
1477
|
+
"_yinc",
|
|
1478
|
+
"_rotation",
|
|
1479
|
+
}
|
|
1480
|
+
for skey, sval in self.__dict__.items():
|
|
1481
|
+
if skey in chklist:
|
|
1482
|
+
for okey, oval in other.__dict__.items():
|
|
1483
|
+
if skey == okey and sval != oval:
|
|
1484
|
+
logger.info("CMP %s: %s vs %s", skey, sval, oval)
|
|
1485
|
+
tstatus = False
|
|
1486
|
+
|
|
1487
|
+
if not tstatus:
|
|
1488
|
+
return False
|
|
1489
|
+
|
|
1490
|
+
# check that masks are equal
|
|
1491
|
+
mas1 = ma.getmaskarray(self.values)
|
|
1492
|
+
mas2 = ma.getmaskarray(other.values)
|
|
1493
|
+
if (
|
|
1494
|
+
strict
|
|
1495
|
+
and isinstance(mas1, np.ndarray)
|
|
1496
|
+
and isinstance(mas2, np.ndarray)
|
|
1497
|
+
and not np.array_equal(mas1, mas2)
|
|
1498
|
+
):
|
|
1499
|
+
logger.warning("Masks differ, not consistent with 'strict'")
|
|
1500
|
+
return False
|
|
1501
|
+
return True
|
|
1502
|
+
|
|
1503
|
+
def swapaxes(self):
|
|
1504
|
+
"""Swap (flip) the axes columns vs rows, keep origin but reverse yflip."""
|
|
1505
|
+
_regsurf_utils.swapaxes(self)
|
|
1506
|
+
|
|
1507
|
+
def make_lefthanded(self) -> None:
|
|
1508
|
+
"""Makes the surface lefthanded in case yflip is -1. This will change origin.
|
|
1509
|
+
|
|
1510
|
+
Lefthanded regular maps are common in subsurface data, where I is to east, J is
|
|
1511
|
+
to north and Z axis is positive down for depth and time data.
|
|
1512
|
+
|
|
1513
|
+
The instance is changed in-place. The method is a no-op if yflip already is 1.
|
|
1514
|
+
|
|
1515
|
+
.. versionadded:: 4.2
|
|
1516
|
+
"""
|
|
1517
|
+
_regsurf_utils.make_lefthanded(self)
|
|
1518
|
+
|
|
1519
|
+
def make_righthanded(self) -> None:
|
|
1520
|
+
"""Makes the surface righthanded in case yflip is 1. This will change origin.
|
|
1521
|
+
|
|
1522
|
+
Righthanded regular maps are less common in subsurface data, where I is to
|
|
1523
|
+
east, J is to north and Z axis is positive down for depth and time data. This
|
|
1524
|
+
method is mainly for consistency since make_lefthanded() is present.
|
|
1525
|
+
|
|
1526
|
+
The instance is changed in-place. The method is a no-op if yflip already is -1.
|
|
1527
|
+
|
|
1528
|
+
.. versionadded:: 4.5
|
|
1529
|
+
"""
|
|
1530
|
+
_regsurf_utils.make_righthanded(self)
|
|
1531
|
+
|
|
1532
|
+
def get_map_xycorners(self):
|
|
1533
|
+
"""Get the X and Y coordinates of the map corners.
|
|
1534
|
+
|
|
1535
|
+
Returns a tuple on the form
|
|
1536
|
+
((x0, y0), (x1, y1), (x2, y2), (x3, y3)) where
|
|
1537
|
+
(if unrotated and normal flip) 0 is the lower left
|
|
1538
|
+
corner, 1 is the right, 2 is the upper left, 3 is the upper right.
|
|
1539
|
+
"""
|
|
1540
|
+
rot1 = self._rotation * math.pi / 180
|
|
1541
|
+
rot2 = rot1 + (math.pi / 2.0)
|
|
1542
|
+
|
|
1543
|
+
xc0 = self._xori
|
|
1544
|
+
yc0 = self._yori
|
|
1545
|
+
|
|
1546
|
+
xc1 = self._xori + (self.ncol - 1) * math.cos(rot1) * self._xinc
|
|
1547
|
+
yc1 = self._yori + (self.ncol - 1) * math.sin(rot1) * self._xinc
|
|
1548
|
+
|
|
1549
|
+
xc2 = self._xori + (self.nrow - 1) * math.cos(rot2) * self._yinc * self._yflip
|
|
1550
|
+
yc2 = self._yori + (self.nrow - 1) * math.sin(rot2) * self._yinc * self._yflip
|
|
1551
|
+
|
|
1552
|
+
xc3 = xc2 + (self.ncol - 1) * math.cos(rot1) * self._xinc
|
|
1553
|
+
yc3 = yc2 + (self.ncol - 1) * math.sin(rot1) * self._xinc
|
|
1554
|
+
|
|
1555
|
+
return ((xc0, yc0), (xc1, yc1), (xc2, yc2), (xc3, yc3))
|
|
1556
|
+
|
|
1557
|
+
def get_value_from_xy(self, point=(0.0, 0.0), sampling="bilinear"):
|
|
1558
|
+
"""Return the map value given a X Y point.
|
|
1559
|
+
|
|
1560
|
+
Args:
|
|
1561
|
+
point (float tuple): Position of X and Y coordinate
|
|
1562
|
+
sampling (str): Sampling method, either "bilinear" for bilinear
|
|
1563
|
+
interpolation, or "nearest" for nearest node sampling (e.g. facies maps)
|
|
1564
|
+
|
|
1565
|
+
Returns:
|
|
1566
|
+
The map value (interpolated). None if XY is outside defined map
|
|
1567
|
+
|
|
1568
|
+
Example::
|
|
1569
|
+
mvalue = map.get_value_from_xy(point=(539291.12, 6788228.2))
|
|
1570
|
+
|
|
1571
|
+
|
|
1572
|
+
.. versionchanged:: 2.14 Added keyword option `sampling`
|
|
1573
|
+
"""
|
|
1574
|
+
return _regsurf_oper.get_value_from_xy(self, point=point, sampling=sampling)
|
|
1575
|
+
|
|
1576
|
+
def get_xy_value_from_ij(self, iloc, jloc, zvalues=None):
|
|
1577
|
+
"""Returns x, y, z(value) from a single i j location.
|
|
1578
|
+
|
|
1579
|
+
Args:
|
|
1580
|
+
iloc (int): I (col) location (base is 1)
|
|
1581
|
+
jloc (int): J (row) location (base is 1)
|
|
1582
|
+
zvalues (ndarray). If this is used in a loop it is wise
|
|
1583
|
+
to precompute the numpy surface once in the caller,
|
|
1584
|
+
and submit the numpy array (use surf.get_values1d()).
|
|
1585
|
+
|
|
1586
|
+
Returns:
|
|
1587
|
+
The x, y, z values at location iloc, jloc
|
|
1588
|
+
"""
|
|
1589
|
+
xval, yval, value = _regsurf_oper.get_xy_value_from_ij(
|
|
1590
|
+
self, iloc, jloc, zvalues=zvalues
|
|
1591
|
+
)
|
|
1592
|
+
|
|
1593
|
+
return xval, yval, value
|
|
1594
|
+
|
|
1595
|
+
def get_ij_values(self, zero_based=False, asmasked=False, order="C"):
|
|
1596
|
+
"""Return I J numpy 2D arrays, optionally as masked arrays.
|
|
1597
|
+
|
|
1598
|
+
Args:
|
|
1599
|
+
zero_based (bool): If False, first number is 1, not 0
|
|
1600
|
+
asmasked (bool): If True, UNDEF map nodes are skipped
|
|
1601
|
+
order (str): 'C' (default) or 'F' order (row vs column major)
|
|
1602
|
+
"""
|
|
1603
|
+
return _regsurf_oper.get_ij_values(
|
|
1604
|
+
self, zero_based=zero_based, asmasked=asmasked, order=order
|
|
1605
|
+
)
|
|
1606
|
+
|
|
1607
|
+
def get_ij_values1d(self, zero_based=False, activeonly=True, order="C"):
|
|
1608
|
+
"""Return I J numpy as 1D arrays.
|
|
1609
|
+
|
|
1610
|
+
Args:
|
|
1611
|
+
zero_based (bool): If False, first number is 1, not 0
|
|
1612
|
+
activeonly (bool): If True, UNDEF map nodes are skipped
|
|
1613
|
+
order (str): 'C' (default) or 'F' order (row vs column major)
|
|
1614
|
+
"""
|
|
1615
|
+
return _regsurf_oper.get_ij_values1d(
|
|
1616
|
+
self, zero_based=zero_based, activeonly=activeonly, order=order
|
|
1617
|
+
)
|
|
1618
|
+
|
|
1619
|
+
def get_xy_values(self, order="C", asmasked=True):
|
|
1620
|
+
"""Return coordinates for X and Y as numpy (masked) 2D arrays.
|
|
1621
|
+
|
|
1622
|
+
Args:
|
|
1623
|
+
order (str): 'C' (default) or 'F' order (row major vs column major)
|
|
1624
|
+
asmasked (bool): If True , inactive nodes are masked.
|
|
1625
|
+
"""
|
|
1626
|
+
xvals, yvals = _regsurf_oper.get_xy_values(self, order=order, asmasked=asmasked)
|
|
1627
|
+
|
|
1628
|
+
return xvals, yvals
|
|
1629
|
+
|
|
1630
|
+
def get_xy_values1d(self, order="C", activeonly=True):
|
|
1631
|
+
"""Return coordinates for X and Y as numpy 1D arrays.
|
|
1632
|
+
|
|
1633
|
+
Args:
|
|
1634
|
+
order (str): 'C' (default) or 'F' order (row major vs column major)
|
|
1635
|
+
activeonly (bool): Only active cells are returned.
|
|
1636
|
+
"""
|
|
1637
|
+
xvals, yvals = _regsurf_oper.get_xy_values1d(
|
|
1638
|
+
self, order=order, activeonly=activeonly
|
|
1639
|
+
)
|
|
1640
|
+
|
|
1641
|
+
return xvals, yvals
|
|
1642
|
+
|
|
1643
|
+
def get_xyz_values(self):
|
|
1644
|
+
"""Return coordinates for X Y and Z (values) as numpy (masked) 2D arrays."""
|
|
1645
|
+
xcoord, ycoord = self.get_xy_values(asmasked=True)
|
|
1646
|
+
|
|
1647
|
+
values = self.values.copy()
|
|
1648
|
+
|
|
1649
|
+
return xcoord, ycoord, values
|
|
1650
|
+
|
|
1651
|
+
def get_xyz_values1d(self, order="C", activeonly=True, fill_value=np.nan):
|
|
1652
|
+
"""Return coordinates for X Y and Z (values) as numpy 1D arrays.
|
|
1653
|
+
|
|
1654
|
+
Args:
|
|
1655
|
+
order (str): 'C' (default) or 'F' order (row major vs column major)
|
|
1656
|
+
activeonly (bool): Only active cells are returned.
|
|
1657
|
+
fill_value (float): If activeonly is False, value of inactive nodes
|
|
1658
|
+
"""
|
|
1659
|
+
xcoord, ycoord = self.get_xy_values1d(order=order, activeonly=activeonly)
|
|
1660
|
+
|
|
1661
|
+
values = self.get_values1d(
|
|
1662
|
+
order=order, asmasked=False, fill_value=fill_value, activeonly=activeonly
|
|
1663
|
+
)
|
|
1664
|
+
|
|
1665
|
+
return xcoord, ycoord, values
|
|
1666
|
+
|
|
1667
|
+
def get_dataframe(
|
|
1668
|
+
self, ijcolumns=False, ij=False, order="C", activeonly=True, fill_value=np.nan
|
|
1669
|
+
):
|
|
1670
|
+
"""Return a Pandas dataframe object, with columns X_UTME, Y_UTMN, VALUES.
|
|
1671
|
+
|
|
1672
|
+
Args:
|
|
1673
|
+
ijcolumns (bool): If True, and IX and JY indices will be
|
|
1674
|
+
added as dataframe columns. Redundant, use "ij" instead.
|
|
1675
|
+
ij (bool): Same as ijcolumns. If True, and IX and JY indices will be
|
|
1676
|
+
added as dataframe columns. Preferred syntax
|
|
1677
|
+
order (str): 'C' (default) for C order (row fastest), or 'F'
|
|
1678
|
+
for Fortran order (column fastest)
|
|
1679
|
+
activeonly (bool): If True, only active nodes are listed. If
|
|
1680
|
+
False, the values will have fill_value default None = NaN
|
|
1681
|
+
as values
|
|
1682
|
+
fill_value (float): Value of inactive nodes if activeonly is False
|
|
1683
|
+
|
|
1684
|
+
Example::
|
|
1685
|
+
|
|
1686
|
+
>>> import xtgeo
|
|
1687
|
+
>>> surf = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
1688
|
+
>>> dfr = surf.get_dataframe()
|
|
1689
|
+
>>> dfr.to_csv('somecsv.csv')
|
|
1690
|
+
|
|
1691
|
+
Returns:
|
|
1692
|
+
A Pandas dataframe object.
|
|
1693
|
+
"""
|
|
1694
|
+
xcoord, ycoord, values = self.get_xyz_values1d(
|
|
1695
|
+
order=order, activeonly=activeonly, fill_value=fill_value
|
|
1696
|
+
)
|
|
1697
|
+
|
|
1698
|
+
entry = {}
|
|
1699
|
+
|
|
1700
|
+
if ijcolumns or ij:
|
|
1701
|
+
ixn, jyn = self.get_ij_values1d(order=order, activeonly=activeonly)
|
|
1702
|
+
entry["IX"] = ixn
|
|
1703
|
+
entry["JY"] = jyn
|
|
1704
|
+
|
|
1705
|
+
entry.update([("X_UTME", xcoord), ("Y_UTMN", ycoord), ("VALUES", values)])
|
|
1706
|
+
|
|
1707
|
+
return pd.DataFrame(entry)
|
|
1708
|
+
|
|
1709
|
+
def dataframe(self, **kwargs):
|
|
1710
|
+
"""Deprecated; see method get_dataframe()."""
|
|
1711
|
+
warnings.warn(
|
|
1712
|
+
"The dataframe() is deprecated and will be removed in xtgeo "
|
|
1713
|
+
"version 5. Use get_dataframe() instead",
|
|
1714
|
+
PendingDeprecationWarning,
|
|
1715
|
+
)
|
|
1716
|
+
|
|
1717
|
+
return self.get_dataframe(**kwargs)
|
|
1718
|
+
|
|
1719
|
+
def get_xy_value_lists(self, lformat="webportal", xyfmt=None, valuefmt=None):
|
|
1720
|
+
"""Returns two lists for coordinates (x, y) and values.
|
|
1721
|
+
|
|
1722
|
+
For lformat = 'webportal' (default):
|
|
1723
|
+
|
|
1724
|
+
The lists are returned as xylist and valuelist, where xylist
|
|
1725
|
+
is on the format:
|
|
1726
|
+
|
|
1727
|
+
[(x1, y1), (x2, y2) ...] (a list of x, y tuples)
|
|
1728
|
+
|
|
1729
|
+
and valuelist is one the format
|
|
1730
|
+
|
|
1731
|
+
[v1, v2, ...]
|
|
1732
|
+
|
|
1733
|
+
Inactive cells will be ignored.
|
|
1734
|
+
|
|
1735
|
+
Args:
|
|
1736
|
+
lformat (string): List return format ('webportal' is default,
|
|
1737
|
+
other options later)
|
|
1738
|
+
xyfmt (string): The formatter for xy numbers, e.g. '12.2f'
|
|
1739
|
+
(default None). Note no checks on valid input.
|
|
1740
|
+
valuefmt (string): The formatter for values e.g. '8.4f'
|
|
1741
|
+
(default None). Note no checks on valid input.
|
|
1742
|
+
|
|
1743
|
+
Returns:
|
|
1744
|
+
xylist, valuelist
|
|
1745
|
+
|
|
1746
|
+
Example:
|
|
1747
|
+
|
|
1748
|
+
>>> import xtgeo
|
|
1749
|
+
>>> surf = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
1750
|
+
>>> xylist, valuelist = surf.get_xy_value_lists(valuefmt='6.2f')
|
|
1751
|
+
"""
|
|
1752
|
+
xylist = []
|
|
1753
|
+
valuelist = []
|
|
1754
|
+
|
|
1755
|
+
zvalues = self.get_values1d()
|
|
1756
|
+
|
|
1757
|
+
if lformat != "webportal":
|
|
1758
|
+
raise ValueError("Unsupported lformat")
|
|
1759
|
+
|
|
1760
|
+
for jnum in range(self.nrow):
|
|
1761
|
+
for inum in range(self.ncol):
|
|
1762
|
+
xcv, ycv, vcv = self.get_xy_value_from_ij(
|
|
1763
|
+
inum + 1, jnum + 1, zvalues=zvalues
|
|
1764
|
+
)
|
|
1765
|
+
|
|
1766
|
+
if vcv is not None:
|
|
1767
|
+
if xyfmt is not None:
|
|
1768
|
+
xcv = float(f"{xcv:{xyfmt}}")
|
|
1769
|
+
ycv = float(f"{ycv:{xyfmt}}")
|
|
1770
|
+
if valuefmt is not None:
|
|
1771
|
+
vcv = float(f"{vcv:{valuefmt}}")
|
|
1772
|
+
valuelist.append(vcv)
|
|
1773
|
+
xylist.append((xcv, ycv))
|
|
1774
|
+
|
|
1775
|
+
return xylist, valuelist
|
|
1776
|
+
|
|
1777
|
+
# ==================================================================================
|
|
1778
|
+
# Crop, interpolation, smooth or fill of values (possibly many methods here)
|
|
1779
|
+
# ==================================================================================
|
|
1780
|
+
|
|
1781
|
+
def autocrop(self):
|
|
1782
|
+
"""Automatic cropping of the surface to minimize undefined areas.
|
|
1783
|
+
|
|
1784
|
+
This method is simply removing undefined "white areas". The
|
|
1785
|
+
instance will be updated with new values for xori, yori, ncol, etc. Rotation
|
|
1786
|
+
will never change
|
|
1787
|
+
|
|
1788
|
+
Returns:
|
|
1789
|
+
RegularSurface instance is updated in-place
|
|
1790
|
+
|
|
1791
|
+
.. versionadded:: 2.12
|
|
1792
|
+
"""
|
|
1793
|
+
_regsurf_utils.autocrop(self)
|
|
1794
|
+
|
|
1795
|
+
def fill(self, fill_value=None):
|
|
1796
|
+
"""Fast infilling of undefined values.
|
|
1797
|
+
|
|
1798
|
+
Note that minimum and maximum values will not change.
|
|
1799
|
+
|
|
1800
|
+
Algorithm if `fill_value` is not set is based on a nearest node extrapolation.
|
|
1801
|
+
Technically, ``scipy.ndimage.distance_transform_edt`` is applied. If fill_value
|
|
1802
|
+
is set by a scalar, that (constant) value be be applied
|
|
1803
|
+
|
|
1804
|
+
Args:
|
|
1805
|
+
fill_value (float): If defined, fills all undefined cells with that value.
|
|
1806
|
+
|
|
1807
|
+
Returns:
|
|
1808
|
+
RegularSurface instance is updated in-place
|
|
1809
|
+
|
|
1810
|
+
.. versionadded:: 2.1
|
|
1811
|
+
.. versionchanged:: 2.6 Added option key `fill_value`
|
|
1812
|
+
"""
|
|
1813
|
+
_regsurf_gridding.surf_fill(self, fill_value=fill_value)
|
|
1814
|
+
|
|
1815
|
+
def smooth(
|
|
1816
|
+
self,
|
|
1817
|
+
method: Literal["median", "gaussian"] = "median",
|
|
1818
|
+
iterations: int = 1,
|
|
1819
|
+
width: float = 1,
|
|
1820
|
+
) -> None:
|
|
1821
|
+
"""Various smoothing methods for surfaces.
|
|
1822
|
+
|
|
1823
|
+
Args:
|
|
1824
|
+
method: Smoothing method (median or gaussian)
|
|
1825
|
+
iterations: Number of iterations
|
|
1826
|
+
width:
|
|
1827
|
+
- If method is 'median' range of influence is in nodes.
|
|
1828
|
+
- If method is 'gaussian' range of influence is standard
|
|
1829
|
+
deviation of the Gaussian kernel.
|
|
1830
|
+
|
|
1831
|
+
.. versionadded:: 2.1
|
|
1832
|
+
"""
|
|
1833
|
+
|
|
1834
|
+
if method == "median":
|
|
1835
|
+
_regsurf_gridding._smooth(
|
|
1836
|
+
self,
|
|
1837
|
+
window_function=functools.partial(
|
|
1838
|
+
scipy.ndimage.median_filter, size=int(width)
|
|
1839
|
+
),
|
|
1840
|
+
iterations=iterations,
|
|
1841
|
+
)
|
|
1842
|
+
elif method == "gaussian":
|
|
1843
|
+
_regsurf_gridding._smooth(
|
|
1844
|
+
self,
|
|
1845
|
+
window_function=functools.partial(
|
|
1846
|
+
scipy.ndimage.gaussian_filter, sigma=width
|
|
1847
|
+
),
|
|
1848
|
+
iterations=iterations,
|
|
1849
|
+
)
|
|
1850
|
+
else:
|
|
1851
|
+
raise ValueError("Unsupported method for smoothing")
|
|
1852
|
+
|
|
1853
|
+
# ==================================================================================
|
|
1854
|
+
# Operation on map values (list to be extended)
|
|
1855
|
+
# ==================================================================================
|
|
1856
|
+
|
|
1857
|
+
def operation(self, opname, value):
|
|
1858
|
+
"""Do operation on map values.
|
|
1859
|
+
|
|
1860
|
+
Do operations on the current map values. Valid operations are:
|
|
1861
|
+
|
|
1862
|
+
* 'elilt' or 'eliminatelessthan': Eliminate less than <value>
|
|
1863
|
+
|
|
1864
|
+
* 'elile' or 'eliminatelessequal': Eliminate less or equal than <value>
|
|
1865
|
+
|
|
1866
|
+
Args:
|
|
1867
|
+
opname (str): Name of operation. See list above.
|
|
1868
|
+
value (*): A scalar number (float) or a tuple of two floats,
|
|
1869
|
+
dependent on operation opname.
|
|
1870
|
+
|
|
1871
|
+
Examples::
|
|
1872
|
+
|
|
1873
|
+
surf.operation('elilt', 200) # set all values < 200 as undef
|
|
1874
|
+
"""
|
|
1875
|
+
if opname in ("elilt", "eliminatelessthan"):
|
|
1876
|
+
self._values = ma.masked_less(self._values, value)
|
|
1877
|
+
elif opname in ("elile", "eliminatelessequal"):
|
|
1878
|
+
self._values = ma.masked_less_equal(self._values, value)
|
|
1879
|
+
else:
|
|
1880
|
+
raise ValueError("Invalid operation name")
|
|
1881
|
+
|
|
1882
|
+
# ==================================================================================
|
|
1883
|
+
# Operations restricted to inside/outside polygons
|
|
1884
|
+
# ==================================================================================
|
|
1885
|
+
|
|
1886
|
+
def operation_polygons(self, poly, value, opname="add", inside=True):
|
|
1887
|
+
"""A generic function for map operations inside or outside polygon(s).
|
|
1888
|
+
|
|
1889
|
+
Args:
|
|
1890
|
+
poly (Polygons): A XTGeo Polygons instance
|
|
1891
|
+
value(float or RegularSurface): Value to add, subtract etc
|
|
1892
|
+
opname (str): Name of operation... 'add', 'sub', etc
|
|
1893
|
+
inside (bool): If True do operation inside polygons; else outside.
|
|
1894
|
+
_version (int): Algorithm version, 2 will be much faster when many points
|
|
1895
|
+
on polygons (this key will be removed in later versions and shall not
|
|
1896
|
+
be applied)
|
|
1897
|
+
"""
|
|
1898
|
+
_regsurf_oper.operation_polygons(
|
|
1899
|
+
self, poly, value, opname=opname, inside=inside
|
|
1900
|
+
)
|
|
1901
|
+
|
|
1902
|
+
# shortforms
|
|
1903
|
+
def add_inside(self, poly, value):
|
|
1904
|
+
"""Add a value (scalar or other map) inside polygons."""
|
|
1905
|
+
self.operation_polygons(poly, value, opname="add", inside=True)
|
|
1906
|
+
|
|
1907
|
+
def add_outside(self, poly, value):
|
|
1908
|
+
"""Add a value (scalar or other map) outside polygons."""
|
|
1909
|
+
self.operation_polygons(poly, value, opname="add", inside=False)
|
|
1910
|
+
|
|
1911
|
+
def sub_inside(self, poly, value):
|
|
1912
|
+
"""Subtract a value (scalar or other map) inside polygons."""
|
|
1913
|
+
self.operation_polygons(poly, value, opname="sub", inside=True)
|
|
1914
|
+
|
|
1915
|
+
def sub_outside(self, poly, value):
|
|
1916
|
+
"""Subtract a value (scalar or other map) outside polygons."""
|
|
1917
|
+
self.operation_polygons(poly, value, opname="sub", inside=False)
|
|
1918
|
+
|
|
1919
|
+
def mul_inside(self, poly, value):
|
|
1920
|
+
"""Multiply a value (scalar or other map) inside polygons."""
|
|
1921
|
+
self.operation_polygons(poly, value, opname="mul", inside=True)
|
|
1922
|
+
|
|
1923
|
+
def mul_outside(self, poly, value):
|
|
1924
|
+
"""Multiply a value (scalar or other map) outside polygons."""
|
|
1925
|
+
self.operation_polygons(poly, value, opname="mul", inside=False)
|
|
1926
|
+
|
|
1927
|
+
def div_inside(self, poly, value):
|
|
1928
|
+
"""Divide a value (scalar or other map) inside polygons."""
|
|
1929
|
+
self.operation_polygons(poly, value, opname="div", inside=True)
|
|
1930
|
+
|
|
1931
|
+
def div_outside(self, poly, value):
|
|
1932
|
+
"""Divide a value (scalar or other map) outside polygons."""
|
|
1933
|
+
self.operation_polygons(poly, value, opname="div", inside=False)
|
|
1934
|
+
|
|
1935
|
+
def set_inside(self, poly, value):
|
|
1936
|
+
"""Set a value (scalar or other map) inside polygons."""
|
|
1937
|
+
self.operation_polygons(poly, value, opname="set", inside=True)
|
|
1938
|
+
|
|
1939
|
+
def set_outside(self, poly, value):
|
|
1940
|
+
"""Set a value (scalar or other map) outside polygons."""
|
|
1941
|
+
self.operation_polygons(poly, value, opname="set", inside=False)
|
|
1942
|
+
|
|
1943
|
+
def eli_inside(self, poly):
|
|
1944
|
+
"""Eliminate current map values inside polygons."""
|
|
1945
|
+
self.operation_polygons(poly, 0, opname="eli", inside=True)
|
|
1946
|
+
|
|
1947
|
+
def eli_outside(self, poly):
|
|
1948
|
+
"""Eliminate current map values outside polygons."""
|
|
1949
|
+
self.operation_polygons(poly, 0, opname="eli", inside=False)
|
|
1950
|
+
|
|
1951
|
+
# ==================================================================================
|
|
1952
|
+
# Operation with secondary map
|
|
1953
|
+
# ==================================================================================
|
|
1954
|
+
|
|
1955
|
+
def add(self, other):
|
|
1956
|
+
"""Add another map to current map."""
|
|
1957
|
+
_regsurf_oper.operations_two(self, other, oper="add")
|
|
1958
|
+
|
|
1959
|
+
def subtract(self, other):
|
|
1960
|
+
"""Subtract another map from current map."""
|
|
1961
|
+
_regsurf_oper.operations_two(self, other, oper="sub")
|
|
1962
|
+
|
|
1963
|
+
def multiply(self, other):
|
|
1964
|
+
"""Multiply another map and current map."""
|
|
1965
|
+
_regsurf_oper.operations_two(self, other, oper="mul")
|
|
1966
|
+
|
|
1967
|
+
def divide(self, other):
|
|
1968
|
+
"""Divide current map with another map."""
|
|
1969
|
+
_regsurf_oper.operations_two(self, other, oper="div")
|
|
1970
|
+
|
|
1971
|
+
# ==================================================================================
|
|
1972
|
+
# Interacion with points
|
|
1973
|
+
# ==================================================================================
|
|
1974
|
+
|
|
1975
|
+
def gridding(self, points, method="linear", coarsen=1):
|
|
1976
|
+
"""Grid a surface from points.
|
|
1977
|
+
|
|
1978
|
+
Args:
|
|
1979
|
+
points(Points): XTGeo Points instance.
|
|
1980
|
+
method (str): Gridding method option: linear / cubic / nearest
|
|
1981
|
+
coarsen (int): Coarsen factor, to speed up gridding, but will
|
|
1982
|
+
give poorer result.
|
|
1983
|
+
|
|
1984
|
+
Example::
|
|
1985
|
+
|
|
1986
|
+
>>> import xtgeo
|
|
1987
|
+
>>> mypoints = xtgeo.Points(points_dir + '/pointset2.poi')
|
|
1988
|
+
>>> mysurf = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
1989
|
+
|
|
1990
|
+
>>> # update the surface by gridding the points
|
|
1991
|
+
>>> mysurf.gridding(mypoints)
|
|
1992
|
+
|
|
1993
|
+
Raises:
|
|
1994
|
+
RuntimeError: If not possible to grid for some reason
|
|
1995
|
+
ValueError: If invalid input
|
|
1996
|
+
|
|
1997
|
+
"""
|
|
1998
|
+
if not isinstance(points, Points):
|
|
1999
|
+
raise ValueError("Argument not a Points instance")
|
|
2000
|
+
|
|
2001
|
+
logger.info("Do gridding...")
|
|
2002
|
+
|
|
2003
|
+
_regsurf_gridding.points_gridding(self, points, coarsen=coarsen, method=method)
|
|
2004
|
+
|
|
2005
|
+
# ==================================================================================
|
|
2006
|
+
# Interacion with other surface
|
|
2007
|
+
# ==================================================================================
|
|
2008
|
+
|
|
2009
|
+
def resample(self, other, mask=True, sampling="bilinear"):
|
|
2010
|
+
"""Resample an instance surface values from another surface instance.
|
|
2011
|
+
|
|
2012
|
+
Note that there may be some 'loss' of nodes at the edges of the
|
|
2013
|
+
updated map, as only the 'inside' nodes in the updated map
|
|
2014
|
+
versus the input map are applied.
|
|
2015
|
+
|
|
2016
|
+
The interpolation algorithm in resample is bilinear interpolation. The
|
|
2017
|
+
topolopogy of the surface (map definitions, rotation, ...) will not change,
|
|
2018
|
+
only the map values. Areas with undefined nodes in ``other`` will become
|
|
2019
|
+
undefined in the instance if mask is True; othewise they will be kept as is.
|
|
2020
|
+
|
|
2021
|
+
Args:
|
|
2022
|
+
other (RegularSurface): Surface to resample from.
|
|
2023
|
+
mask (bool): If True (default) nodes outside will be made undefined,
|
|
2024
|
+
if False then values will be kept as original
|
|
2025
|
+
sampling (str): Either 'bilinear' interpolation (default) or, 'nearest' for
|
|
2026
|
+
nearest node. The latter can be useful for resampling discrete maps.
|
|
2027
|
+
|
|
2028
|
+
Example::
|
|
2029
|
+
|
|
2030
|
+
# map with 230x210 columns, rotation 20
|
|
2031
|
+
surf1 = xtgeo.surface_from_file("some1.gri")
|
|
2032
|
+
# map with 270x190 columns, rotation 0
|
|
2033
|
+
surf2 = xtgeo.surface_from_file("some2.gri")
|
|
2034
|
+
# will sample (interpolate) surf2's values to surf1
|
|
2035
|
+
surf1.resample(surf2)
|
|
2036
|
+
|
|
2037
|
+
Returns:
|
|
2038
|
+
Instance's surface values will be updated in-place.
|
|
2039
|
+
|
|
2040
|
+
|
|
2041
|
+
.. versionchanged:: 2.9
|
|
2042
|
+
Added ``mask`` keyword, default is True for backward compatibility.
|
|
2043
|
+
|
|
2044
|
+
.. versionchanged:: 2.21
|
|
2045
|
+
Added ``sampling`` keyword option.
|
|
2046
|
+
|
|
2047
|
+
"""
|
|
2048
|
+
if not isinstance(other, RegularSurface):
|
|
2049
|
+
raise ValueError("Argument not a RegularSurface instance")
|
|
2050
|
+
|
|
2051
|
+
logger.info("Do resampling...")
|
|
2052
|
+
|
|
2053
|
+
_regsurf_oper.resample(self, other, mask=mask, sampling=sampling)
|
|
2054
|
+
|
|
2055
|
+
# ==================================================================================
|
|
2056
|
+
# Change a surface more fundamentally
|
|
2057
|
+
# ==================================================================================
|
|
2058
|
+
|
|
2059
|
+
def unrotate(self, factor=2):
|
|
2060
|
+
r"""Unrotete a map instance, and this will also change nrow, ncol, xinc, etc.
|
|
2061
|
+
|
|
2062
|
+
The default sampling (factor=2) makes a finer grid in order to
|
|
2063
|
+
avoid artifacts, and this default can be used in most cases.
|
|
2064
|
+
|
|
2065
|
+
If an even finer grid is wanted, increase the factor. Theoretically the
|
|
2066
|
+
new increment for factor=N is between :math:`\\frac{1}{N}` and
|
|
2067
|
+
:math:`\\frac{1}{N}\\sqrt{2}` of the original increment,
|
|
2068
|
+
dependent on the rotation of the original surface.
|
|
2069
|
+
|
|
2070
|
+
If the current instance already is unrotated, nothing is done.
|
|
2071
|
+
|
|
2072
|
+
Args:
|
|
2073
|
+
factor (int): Refinement factor (>= 1)
|
|
2074
|
+
|
|
2075
|
+
"""
|
|
2076
|
+
if abs(self.rotation) < 0.00001:
|
|
2077
|
+
logger.info("Surface has no rotation, nothing is done")
|
|
2078
|
+
return
|
|
2079
|
+
|
|
2080
|
+
if factor < 1:
|
|
2081
|
+
raise ValueError("Unrotate refinement factor cannot be be less than 1")
|
|
2082
|
+
|
|
2083
|
+
if not isinstance(factor, int):
|
|
2084
|
+
raise ValueError("Refinementfactor must an integer")
|
|
2085
|
+
|
|
2086
|
+
scopy = self
|
|
2087
|
+
if scopy._yflip < 0:
|
|
2088
|
+
scopy = self.copy()
|
|
2089
|
+
scopy.swapaxes()
|
|
2090
|
+
|
|
2091
|
+
xlen = scopy.xmax - scopy.xmin
|
|
2092
|
+
ylen = scopy.ymax - scopy.ymin
|
|
2093
|
+
ncol = scopy.ncol * factor
|
|
2094
|
+
nrow = scopy.nrow * factor
|
|
2095
|
+
xinc = xlen / (ncol - 1) # node based, not cell center based
|
|
2096
|
+
yinc = ylen / (nrow - 1)
|
|
2097
|
+
vals = ma.zeros((ncol, nrow), order="C")
|
|
2098
|
+
|
|
2099
|
+
nonrot = RegularSurface(
|
|
2100
|
+
xori=scopy.xmin,
|
|
2101
|
+
yori=scopy.ymin,
|
|
2102
|
+
xinc=xinc,
|
|
2103
|
+
yinc=yinc,
|
|
2104
|
+
ncol=ncol,
|
|
2105
|
+
nrow=nrow,
|
|
2106
|
+
values=vals,
|
|
2107
|
+
yflip=1,
|
|
2108
|
+
)
|
|
2109
|
+
nonrot.resample(scopy)
|
|
2110
|
+
|
|
2111
|
+
self._values = nonrot.values
|
|
2112
|
+
self._nrow = nonrot.nrow
|
|
2113
|
+
self._ncol = nonrot.ncol
|
|
2114
|
+
self._rotation = nonrot.rotation
|
|
2115
|
+
self._xori = nonrot.xori
|
|
2116
|
+
self._yori = nonrot.yori
|
|
2117
|
+
self._xinc = nonrot.xinc
|
|
2118
|
+
self._yinc = nonrot.yinc
|
|
2119
|
+
self._yflip = nonrot.yflip
|
|
2120
|
+
self._ilines = nonrot.ilines
|
|
2121
|
+
self._xlines = nonrot.xlines
|
|
2122
|
+
|
|
2123
|
+
def refine(self, factor):
|
|
2124
|
+
"""Refine a surface with a factor.
|
|
2125
|
+
|
|
2126
|
+
Range for factor is 2 to 10.
|
|
2127
|
+
|
|
2128
|
+
Note that there may be some 'loss' of nodes at the edges of the
|
|
2129
|
+
updated map, as only the 'inside' nodes in the updated map
|
|
2130
|
+
versus the input map are applied.
|
|
2131
|
+
|
|
2132
|
+
Args:
|
|
2133
|
+
factor (int): Refinement factor
|
|
2134
|
+
"""
|
|
2135
|
+
logger.info("Do refining...")
|
|
2136
|
+
|
|
2137
|
+
if not isinstance(factor, int):
|
|
2138
|
+
raise ValueError("Argument not a, Integer")
|
|
2139
|
+
|
|
2140
|
+
if factor < 2 or factor >= 10:
|
|
2141
|
+
raise ValueError("Argument exceeds range 2 .. 10")
|
|
2142
|
+
|
|
2143
|
+
xlen = self._xinc * (self._ncol - 1)
|
|
2144
|
+
ylen = self._yinc * (self._nrow - 1)
|
|
2145
|
+
|
|
2146
|
+
proxy = self.copy()
|
|
2147
|
+
self._ncol = proxy.ncol * factor
|
|
2148
|
+
self._nrow = proxy.nrow * factor
|
|
2149
|
+
self._xinc = xlen / (self._ncol - 1)
|
|
2150
|
+
self._yinc = ylen / (self._nrow - 1)
|
|
2151
|
+
|
|
2152
|
+
self._values = ma.zeros((self._ncol, self._nrow))
|
|
2153
|
+
|
|
2154
|
+
self._ilines = np.array(range(1, self._ncol + 1), dtype=np.int32)
|
|
2155
|
+
self._xlines = np.array(range(1, self._nrow + 1), dtype=np.int32)
|
|
2156
|
+
|
|
2157
|
+
self.resample(proxy)
|
|
2158
|
+
|
|
2159
|
+
del proxy
|
|
2160
|
+
logger.info("Do refining... done")
|
|
2161
|
+
|
|
2162
|
+
def coarsen(self, factor):
|
|
2163
|
+
"""Coarsen a surface with a factor.
|
|
2164
|
+
|
|
2165
|
+
Range for coarsening is 2 to 10, where e.g. 2 meaning half the number of
|
|
2166
|
+
columns and rows.
|
|
2167
|
+
|
|
2168
|
+
Note that there may be some 'loss' of nodes at the edges of the
|
|
2169
|
+
updated map, as only the 'inside' nodes in the updated map
|
|
2170
|
+
versus the input map are applied.
|
|
2171
|
+
|
|
2172
|
+
Args:
|
|
2173
|
+
factor (int): Coarsen factor (2 .. 10)
|
|
2174
|
+
|
|
2175
|
+
Raises:
|
|
2176
|
+
ValueError: Coarsen is too large, giving too few nodes in result
|
|
2177
|
+
"""
|
|
2178
|
+
logger.info("Do coarsening...")
|
|
2179
|
+
if not isinstance(factor, int):
|
|
2180
|
+
raise ValueError("Argument not a, Integer")
|
|
2181
|
+
|
|
2182
|
+
if factor < 2 or factor >= 10:
|
|
2183
|
+
raise ValueError("Argument exceeds range 2 .. 10")
|
|
2184
|
+
|
|
2185
|
+
proxy = self.copy()
|
|
2186
|
+
xlen = self._xinc * (self._ncol - 1)
|
|
2187
|
+
ylen = self._yinc * (self._nrow - 1)
|
|
2188
|
+
|
|
2189
|
+
ncol = int(round(proxy._ncol / factor))
|
|
2190
|
+
nrow = int(round(proxy._nrow / factor))
|
|
2191
|
+
|
|
2192
|
+
if ncol < 4 or nrow < 4:
|
|
2193
|
+
raise ValueError(
|
|
2194
|
+
"Coarsen is too large, giving ncol or nrow less than 4 nodes"
|
|
2195
|
+
)
|
|
2196
|
+
|
|
2197
|
+
self._ncol = ncol
|
|
2198
|
+
self._nrow = nrow
|
|
2199
|
+
|
|
2200
|
+
self._xinc = xlen / (self._ncol - 1)
|
|
2201
|
+
self._yinc = ylen / (self._nrow - 1)
|
|
2202
|
+
|
|
2203
|
+
self._values = ma.zeros((self._ncol, self._nrow))
|
|
2204
|
+
|
|
2205
|
+
self._ilines = np.array(range(1, self._ncol + 1), dtype=np.int32)
|
|
2206
|
+
self._xlines = np.array(range(1, self._nrow + 1), dtype=np.int32)
|
|
2207
|
+
|
|
2208
|
+
self.resample(proxy)
|
|
2209
|
+
|
|
2210
|
+
del proxy
|
|
2211
|
+
logger.info("Do coarsening... done")
|
|
2212
|
+
|
|
2213
|
+
# ==================================================================================
|
|
2214
|
+
# Interacion with a grid3d
|
|
2215
|
+
# ==================================================================================
|
|
2216
|
+
|
|
2217
|
+
def slice_grid3d(self, grid, prop, zsurf=None, sbuffer=1):
|
|
2218
|
+
"""Slice the grid property and update the instance surface to sampled values.
|
|
2219
|
+
|
|
2220
|
+
Args:
|
|
2221
|
+
grid (Grid): Instance of a Grid.
|
|
2222
|
+
prop (GridProperty): Instance of a GridProperty, belongs to grid
|
|
2223
|
+
zsurf (surface object): Instance of map, which is used a slicer.
|
|
2224
|
+
If None, then the surface instance itself is used a slice
|
|
2225
|
+
criteria. Note that zsurf must have same map defs as the
|
|
2226
|
+
surface instance.
|
|
2227
|
+
sbuffer (int): Default is 1; if "holes" after sampling
|
|
2228
|
+
extend this to e.g. 3
|
|
2229
|
+
Example::
|
|
2230
|
+
|
|
2231
|
+
>>> import xtgeo
|
|
2232
|
+
>>> grd = xtgeo.grid_from_file(reek_dir + '/REEK.EGRID')
|
|
2233
|
+
>>> prop = xtgeo.gridproperty_from_file(
|
|
2234
|
+
... reek_dir + '/REEK.UNRST',
|
|
2235
|
+
... name='PRESSURE',
|
|
2236
|
+
... date="first",
|
|
2237
|
+
... grid=grd,
|
|
2238
|
+
... )
|
|
2239
|
+
>>> surf = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
2240
|
+
>>> # update surf to sample the 3D grid property:
|
|
2241
|
+
>>> surf.slice_grid3d(grd, prop)
|
|
2242
|
+
|
|
2243
|
+
Raises:
|
|
2244
|
+
Exception if maps have different definitions (topology)
|
|
2245
|
+
"""
|
|
2246
|
+
# TODO: Remove this when circular dependency untangled
|
|
2247
|
+
from xtgeo.grid3d.grid import Grid
|
|
2248
|
+
|
|
2249
|
+
if not isinstance(grid, Grid):
|
|
2250
|
+
raise ValueError("First argument must be a grid instance")
|
|
2251
|
+
|
|
2252
|
+
ier = _regsurf_grid3d.slice_grid3d(
|
|
2253
|
+
self, grid, prop, zsurf=zsurf, sbuffer=sbuffer
|
|
2254
|
+
)
|
|
2255
|
+
|
|
2256
|
+
if ier != 0:
|
|
2257
|
+
raise RuntimeError(
|
|
2258
|
+
"Wrong status from routine; something went wrong. Contact the author"
|
|
2259
|
+
)
|
|
2260
|
+
|
|
2261
|
+
# ==================================================================================
|
|
2262
|
+
# Interacion with a cube
|
|
2263
|
+
# ==================================================================================
|
|
2264
|
+
|
|
2265
|
+
def slice_cube(
|
|
2266
|
+
self,
|
|
2267
|
+
cube,
|
|
2268
|
+
zsurf=None,
|
|
2269
|
+
sampling="nearest",
|
|
2270
|
+
mask=True,
|
|
2271
|
+
snapxy=False,
|
|
2272
|
+
deadtraces=True,
|
|
2273
|
+
algorithm=2,
|
|
2274
|
+
):
|
|
2275
|
+
"""Slice the cube and update the instance surface to sampled cube values.
|
|
2276
|
+
|
|
2277
|
+
Args:
|
|
2278
|
+
cube (object): Instance of a Cube()
|
|
2279
|
+
zsurf (surface object): Instance of a depth (or time) map, which
|
|
2280
|
+
is the depth or time map (or...) that is used a slicer.
|
|
2281
|
+
If None, then the surface instance itself is used a slice
|
|
2282
|
+
criteria. Note that zsurf must have same map defs as the
|
|
2283
|
+
surface instance.
|
|
2284
|
+
sampling (str): 'nearest' for nearest node (default), or
|
|
2285
|
+
'trilinear' for trilinear interpolation.
|
|
2286
|
+
mask (bool): If True (default), then the map values outside
|
|
2287
|
+
the cube will be undef. Otherwise, map will be kept as is.
|
|
2288
|
+
snapxy (bool): If True (optional), then the map values will get
|
|
2289
|
+
values at nearest Cube XY location. Only relevant to use if
|
|
2290
|
+
surface is derived from seismic coordinates (e.g. Auto4D).
|
|
2291
|
+
deadtraces (bool): If True (default) then dead cube traces
|
|
2292
|
+
(given as value 2 in SEGY trace headers), are treated as
|
|
2293
|
+
undefined, and map will become undefined at dead trace location.
|
|
2294
|
+
algorithm (int): 1 for legacy method, 2 (default from 2.9) for
|
|
2295
|
+
new method available in xtgeo from version 2.9
|
|
2296
|
+
|
|
2297
|
+
Example::
|
|
2298
|
+
|
|
2299
|
+
>>> import xtgeo
|
|
2300
|
+
>>> cube = xtgeo.cube_from_file(cube_dir + "/ib_test_cube2.segy")
|
|
2301
|
+
>>> surf = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
2302
|
+
>>> # update surf to sample cube values:
|
|
2303
|
+
>>> surf.slice_cube(cube)
|
|
2304
|
+
|
|
2305
|
+
Raises:
|
|
2306
|
+
Exception if maps have different definitions (topology)
|
|
2307
|
+
RuntimeWarning if number of sampled nodes is less than 10%
|
|
2308
|
+
|
|
2309
|
+
.. versionchanged:: 2.9 Added ``algorithm`` keyword, default is 2
|
|
2310
|
+
"""
|
|
2311
|
+
scube = surface_from_cube(cube, 0)
|
|
2312
|
+
ier = _regsurf_cube.slice_cube(
|
|
2313
|
+
self,
|
|
2314
|
+
cube,
|
|
2315
|
+
scube,
|
|
2316
|
+
zsurf=zsurf,
|
|
2317
|
+
sampling=sampling,
|
|
2318
|
+
mask=mask,
|
|
2319
|
+
snapxy=snapxy,
|
|
2320
|
+
deadtraces=deadtraces,
|
|
2321
|
+
algorithm=algorithm,
|
|
2322
|
+
)
|
|
2323
|
+
|
|
2324
|
+
if ier == -4:
|
|
2325
|
+
xtg.warnuser("Number of sampled surface nodes < 10 percent of Cube nodes")
|
|
2326
|
+
print("Number of sampled surface nodes < 10 percent of Cube nodes")
|
|
2327
|
+
elif ier == -5:
|
|
2328
|
+
xtg.warn("No nodes sampled: map is 100 percent outside of cube?")
|
|
2329
|
+
|
|
2330
|
+
def slice_cube_window(
|
|
2331
|
+
self,
|
|
2332
|
+
cube: Cube,
|
|
2333
|
+
zsurf: Optional[RegularSurface] = None,
|
|
2334
|
+
other: Optional[RegularSurface] = None,
|
|
2335
|
+
other_position: str = "below",
|
|
2336
|
+
sampling: Literal["nearest", "cube", "trilinear"] = "nearest",
|
|
2337
|
+
mask: bool = True,
|
|
2338
|
+
zrange: Optional[float] = None,
|
|
2339
|
+
ndiv: Optional[int] = None,
|
|
2340
|
+
attribute: Union[List[ValidAttrs], ValidAttrs] = "max",
|
|
2341
|
+
maskthreshold: float = 0.1,
|
|
2342
|
+
snapxy: bool = False,
|
|
2343
|
+
showprogress: bool = False,
|
|
2344
|
+
deadtraces: bool = True,
|
|
2345
|
+
algorithm: Literal[1, 2, 3] = 2,
|
|
2346
|
+
) -> Optional[Dict[RegularSurface]]:
|
|
2347
|
+
"""Slice the cube within a vertical window and get the statistical attrubutes.
|
|
2348
|
+
|
|
2349
|
+
The statistical attributes can be min, max etc. Attributes are:
|
|
2350
|
+
|
|
2351
|
+
* 'max' for maximum
|
|
2352
|
+
|
|
2353
|
+
* 'min' for minimum
|
|
2354
|
+
|
|
2355
|
+
* 'rms' for root mean square
|
|
2356
|
+
|
|
2357
|
+
* 'mean' for expected value
|
|
2358
|
+
|
|
2359
|
+
* 'var' for variance (population var; https://en.wikipedia.org/wiki/Variance)
|
|
2360
|
+
|
|
2361
|
+
* 'maxpos' for maximum of positive values
|
|
2362
|
+
|
|
2363
|
+
* 'maxneg' for negative maximum of negative values
|
|
2364
|
+
|
|
2365
|
+
* 'maxabs' for maximum of absolute values
|
|
2366
|
+
|
|
2367
|
+
* 'sumpos' for sum of positive values using cube sampling resolution
|
|
2368
|
+
|
|
2369
|
+
* 'sumneg' for sum of negative values using cube sampling resolution
|
|
2370
|
+
|
|
2371
|
+
* 'meanabs' for mean of absolute values
|
|
2372
|
+
|
|
2373
|
+
* 'meanpos' for mean of positive values
|
|
2374
|
+
|
|
2375
|
+
* 'meanneg' for mean of negative values
|
|
2376
|
+
|
|
2377
|
+
Note that 'all' can be used to select all attributes that are currently
|
|
2378
|
+
available.
|
|
2379
|
+
|
|
2380
|
+
Args:
|
|
2381
|
+
cube: Instance of a Cube() here
|
|
2382
|
+
zsurf: Instance of a depth (or time) map, which
|
|
2383
|
+
is the depth or time map (or...) that is used a slicer.
|
|
2384
|
+
If None, then the surface instance itself is used a slice
|
|
2385
|
+
criteria. Note that zsurf must have same map defs as the
|
|
2386
|
+
surface instance.
|
|
2387
|
+
other: Instance of other surface if window is
|
|
2388
|
+
between surfaces instead of a static window. The zrange
|
|
2389
|
+
input is then not applied.
|
|
2390
|
+
sampling: 'nearest'/'trilinear'/'cube' for nearest node (default),
|
|
2391
|
+
or 'trilinear' for trilinear interpolation. The 'cube' option is
|
|
2392
|
+
only available with algorithm = 2 and will overrule ndiv and sample
|
|
2393
|
+
at the cube's Z increment resolution.
|
|
2394
|
+
mask: If True (default), then the map values outside
|
|
2395
|
+
the cube will be undef, otherwise map will be kept as-is
|
|
2396
|
+
zrange: The one-sided "radius" range of the window, e.g. 10
|
|
2397
|
+
(10 is default) units (e.g. meters if in depth mode).
|
|
2398
|
+
The full window is +- zrange (i.e. diameter).
|
|
2399
|
+
If other surface is present, zrange is computed based on those
|
|
2400
|
+
two surfaces instead.
|
|
2401
|
+
ndiv: Number of intervals for sampling within zrange. None
|
|
2402
|
+
means 'auto' sampling, using 0.5 of cube Z increment as basis. If
|
|
2403
|
+
algorithm = 2/3 and sampling is 'cube', the cube Z increment
|
|
2404
|
+
will be used.
|
|
2405
|
+
attribute: The requested attribute(s), e.g.
|
|
2406
|
+
'max' value. May also be a list of attributes, e.g.
|
|
2407
|
+
['min', 'rms', 'max']. By such, a dict of surface objects is
|
|
2408
|
+
returned. Note 'all' will make a list of all possible attributes.
|
|
2409
|
+
maskthreshold (float): Only if two surface; if isochore is less
|
|
2410
|
+
than given value, the result will be masked.
|
|
2411
|
+
snapxy: If True (optional), then the map values will get
|
|
2412
|
+
values at nearest Cube XY location, and the resulting surfaces layout
|
|
2413
|
+
map will be defined by the seismic layout. Quite relevant to use if
|
|
2414
|
+
surface is derived from seismic coordinates (e.g. Auto4D), but can be
|
|
2415
|
+
useful in other cases also, as long as one notes that map definition
|
|
2416
|
+
may change from input.
|
|
2417
|
+
showprogress: If True, then a progress is printed to stdout.
|
|
2418
|
+
deadtraces: If True (default) then dead cube traces
|
|
2419
|
+
(given as value 2 in SEGY trace headers), are treated as
|
|
2420
|
+
undefined, and map will be undefined at dead trace location.
|
|
2421
|
+
algorithm: 1 for legacy method, 2 (default) for new faster
|
|
2422
|
+
and more precise method available from xtgeo version 2.9, and
|
|
2423
|
+
algorithm 3 as new implementation from Sept. 2023 (v3.4)
|
|
2424
|
+
|
|
2425
|
+
Example::
|
|
2426
|
+
|
|
2427
|
+
>>> import xtgeo
|
|
2428
|
+
>>> cube = xtgeo.cube_from_file(cube_dir + "/ib_test_cube2.segy")
|
|
2429
|
+
>>> surf = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
2430
|
+
>>> # update surf to sample cube values in a total range of 30 m:
|
|
2431
|
+
>>> surf.slice_cube_window(cube, attribute='min', zrange=15.0)
|
|
2432
|
+
|
|
2433
|
+
>>> # Here a list is given instead:
|
|
2434
|
+
>>> alst = ['min', 'max', 'rms']
|
|
2435
|
+
|
|
2436
|
+
>>> myattrs = surf.slice_cube_window(cube, attribute=alst, zrange=15.0)
|
|
2437
|
+
>>> for attr in myattrs.keys():
|
|
2438
|
+
... _ = myattrs[attr].to_file(
|
|
2439
|
+
... outdir + '/myfile_' + attr + '.gri'
|
|
2440
|
+
... )
|
|
2441
|
+
|
|
2442
|
+
Raises:
|
|
2443
|
+
Exception if maps have different definitions (topology)
|
|
2444
|
+
ValueError if attribute is invalid.
|
|
2445
|
+
|
|
2446
|
+
Returns:
|
|
2447
|
+
If `attribute` is a string, then the instance is updated and
|
|
2448
|
+
None is returned. If `attribute` is a list, then a dictionary
|
|
2449
|
+
of surface objects is returned.
|
|
2450
|
+
|
|
2451
|
+
Note:
|
|
2452
|
+
This method is now deprecated and will be removed in xtgeo version 5.
|
|
2453
|
+
Please replace with :meth:`Cube().compute_attributes_in_window()` as soon
|
|
2454
|
+
as possible.
|
|
2455
|
+
|
|
2456
|
+
|
|
2457
|
+
.. versionchanged:: 2.9 Added ``algorithm`` keyword, default is now 2,
|
|
2458
|
+
while 1 is the legacy version
|
|
2459
|
+
|
|
2460
|
+
.. versionchanged:: 3.4 Added ``algorithm`` 3 which is more robust and
|
|
2461
|
+
hence recommended!
|
|
2462
|
+
|
|
2463
|
+
.. versionchanged:: 4.1 Flagged as deprecated.
|
|
2464
|
+
|
|
2465
|
+
"""
|
|
2466
|
+
|
|
2467
|
+
warnings.warn(
|
|
2468
|
+
"This method is deprecated and will be removed in xtgeo version 5. "
|
|
2469
|
+
"It is strongly recommended to use `Cube().compute_attributes_in_window()` "
|
|
2470
|
+
"instead!",
|
|
2471
|
+
FutureWarning,
|
|
2472
|
+
)
|
|
2473
|
+
|
|
2474
|
+
if other is None and zrange is None:
|
|
2475
|
+
zrange = 10
|
|
2476
|
+
|
|
2477
|
+
if algorithm != 3:
|
|
2478
|
+
warnings.warn(
|
|
2479
|
+
"Other algorithms than no. 3 is not recommended, and will be "
|
|
2480
|
+
"removed in near future.",
|
|
2481
|
+
DeprecationWarning,
|
|
2482
|
+
)
|
|
2483
|
+
|
|
2484
|
+
scube = surface_from_cube(cube, 0)
|
|
2485
|
+
return _regsurf_cube_window.slice_cube_window(
|
|
2486
|
+
self,
|
|
2487
|
+
cube,
|
|
2488
|
+
scube,
|
|
2489
|
+
zsurf=zsurf,
|
|
2490
|
+
other=other,
|
|
2491
|
+
other_position=other_position,
|
|
2492
|
+
sampling=sampling,
|
|
2493
|
+
mask=mask,
|
|
2494
|
+
zrange=zrange,
|
|
2495
|
+
ndiv=ndiv,
|
|
2496
|
+
attribute=attribute,
|
|
2497
|
+
maskthreshold=maskthreshold,
|
|
2498
|
+
snapxy=snapxy,
|
|
2499
|
+
showprogress=showprogress,
|
|
2500
|
+
deadtraces=deadtraces,
|
|
2501
|
+
algorithm=algorithm,
|
|
2502
|
+
)
|
|
2503
|
+
|
|
2504
|
+
# ==================================================================================
|
|
2505
|
+
# Special methods
|
|
2506
|
+
# ==================================================================================
|
|
2507
|
+
|
|
2508
|
+
def get_boundary_polygons(
|
|
2509
|
+
self,
|
|
2510
|
+
alpha_factor: Optional[float] = 1.0,
|
|
2511
|
+
convex: Optional[bool] = False,
|
|
2512
|
+
simplify: Optional[bool] = True,
|
|
2513
|
+
):
|
|
2514
|
+
"""Extract boundary polygons from the surface.
|
|
2515
|
+
|
|
2516
|
+
A regular surface may often contain areas of undefined (masked) entries which
|
|
2517
|
+
makes the surface appear 'ragged' and/or 'patchy'.
|
|
2518
|
+
|
|
2519
|
+
This method extracts boundaries around the surface patches, and the
|
|
2520
|
+
precision depends on the keyword settings. As default, the ``alpha_factor``
|
|
2521
|
+
of 1 makes a precise boundary, while a larger alpha_factor makes more rough
|
|
2522
|
+
polygons.
|
|
2523
|
+
|
|
2524
|
+
.. image:: images/regsurf_boundary_polygons.png
|
|
2525
|
+
:width: 600
|
|
2526
|
+
:align: center
|
|
2527
|
+
|
|
2528
|
+
|
|
|
2529
|
+
|
|
2530
|
+
Args:
|
|
2531
|
+
alpha_factor: An alpha multiplier, where lowest allowed value is 1.0.
|
|
2532
|
+
A higher number will produce smoother and less accurate polygons. Not
|
|
2533
|
+
applied if convex is set to True.
|
|
2534
|
+
convex: The default is False, which means that a "concave hull" algorithm
|
|
2535
|
+
is used. If convex is True, the alpha factor is overridden to a large
|
|
2536
|
+
number, producing a 'convex' shape boundary instead.
|
|
2537
|
+
simplify: If True, a simplification is done in order to reduce the number
|
|
2538
|
+
of points in the polygons, where tolerance is 0.1. Another
|
|
2539
|
+
alternative to True is to input a Dict on the form
|
|
2540
|
+
``{"tolerance": 2.0, "preserve_topology": True}``, cf. the
|
|
2541
|
+
:func:`Polygons.simplify()` method. For details on e.g. tolerance, see
|
|
2542
|
+
Shapely's simplify() method.
|
|
2543
|
+
|
|
2544
|
+
Returns:
|
|
2545
|
+
A XTGeo Polygons instance
|
|
2546
|
+
|
|
2547
|
+
Example::
|
|
2548
|
+
|
|
2549
|
+
surf = xtgeo.surface_from_file("mytop.gri")
|
|
2550
|
+
# eliminate all values below a depth, e.g. a fluid contact
|
|
2551
|
+
surf.values = np.ma.masked_greater(surf.values, 2100.0)
|
|
2552
|
+
boundary = surf.get_boundary_polygons()
|
|
2553
|
+
# the boundary may contain several smaller polygons; keep only the
|
|
2554
|
+
# largest (first) polygon which is number 0:
|
|
2555
|
+
boundary.filter_byid([0]) # polygon is updated in-place
|
|
2556
|
+
|
|
2557
|
+
See also:
|
|
2558
|
+
The :func:`Polygons.boundary_from_points()` class method.
|
|
2559
|
+
|
|
2560
|
+
.. versionadded:: 3.1
|
|
2561
|
+
"""
|
|
2562
|
+
return _regsurf_boundary.create_boundary(self, alpha_factor, convex, simplify)
|
|
2563
|
+
|
|
2564
|
+
def get_fence(
|
|
2565
|
+
self, xyfence: np.ndarray, sampling: Optional[str] = "bilinear"
|
|
2566
|
+
) -> np.ma.MaskedArray:
|
|
2567
|
+
"""Sample the surface along X and Y positions (numpy arrays) and get Z.
|
|
2568
|
+
|
|
2569
|
+
.. versionchanged:: 2.14 Added keyword option `sampling`
|
|
2570
|
+
|
|
2571
|
+
Returns a masked numpy 2D array similar as input, but with updated
|
|
2572
|
+
Z values, which are masked if undefined.
|
|
2573
|
+
|
|
2574
|
+
Args:
|
|
2575
|
+
xyfence: A 2D numpy array with shape (N, 3) where columns
|
|
2576
|
+
are (X, Y, Z). The Z will be updated to the map.
|
|
2577
|
+
sampling: Use "bilinear" (default) for interpolation or "nearest" for
|
|
2578
|
+
snapping to nearest node.
|
|
2579
|
+
|
|
2580
|
+
"""
|
|
2581
|
+
return _regsurf_oper.get_fence(self, xyfence, sampling=sampling)
|
|
2582
|
+
|
|
2583
|
+
def get_randomline(
|
|
2584
|
+
self,
|
|
2585
|
+
fencespec: Union[np.ndarray, object],
|
|
2586
|
+
hincrement: Optional[Union[bool, float]] = None,
|
|
2587
|
+
atleast: Optional[int] = 5,
|
|
2588
|
+
nextend: Optional[int] = 2,
|
|
2589
|
+
sampling: Optional[str] = "bilinear",
|
|
2590
|
+
) -> np.ndarray:
|
|
2591
|
+
"""Extract a line along a fencespec.
|
|
2592
|
+
|
|
2593
|
+
.. versionadded:: 2.1
|
|
2594
|
+
.. versionchanged:: 2.14 Added keyword option `sampling`
|
|
2595
|
+
|
|
2596
|
+
Here, horizontal axis is "length" and vertical axis is sampled depth, and
|
|
2597
|
+
this is used for fence plots.
|
|
2598
|
+
|
|
2599
|
+
The input fencespec is either a 2D numpy where each row is X, Y, Z, HLEN,
|
|
2600
|
+
where X, Y are UTM coordinates, Z is depth/time, and HLEN is a
|
|
2601
|
+
length along the fence, or a Polygons instance.
|
|
2602
|
+
|
|
2603
|
+
If input fencspec is a numpy 2D, it is important that the HLEN array
|
|
2604
|
+
has a constant increment and ideally a sampling that is less than the
|
|
2605
|
+
map resolution. If a Polygons() instance, this is automated if hincrement is
|
|
2606
|
+
None, and ignored if hincrement is False.
|
|
2607
|
+
|
|
2608
|
+
Returns a ndarray with shape (:, 2).
|
|
2609
|
+
|
|
2610
|
+
Args:
|
|
2611
|
+
fencespec:
|
|
2612
|
+
2D numpy with X, Y, Z, HLEN as rows or a xtgeo Polygons() object.
|
|
2613
|
+
hincrement: Resampling horizontally. This applies only
|
|
2614
|
+
if the fencespec is a Polygons() instance. If None (default),
|
|
2615
|
+
the distance will be deduced automatically. If False, then it assumes
|
|
2616
|
+
the Polygons can be used as-is.
|
|
2617
|
+
atleast: Minimum number of horizontal samples (only if
|
|
2618
|
+
fencespec is a Polygons instance and hincrement != False)
|
|
2619
|
+
nextend: Extend with nextend * hincrement in both ends (only if
|
|
2620
|
+
fencespec is a Polygons instance and hincrement != False)
|
|
2621
|
+
sampling: Use "bilinear" (default) for interpolation or "nearest" for
|
|
2622
|
+
snapping to nearest node.
|
|
2623
|
+
|
|
2624
|
+
|
|
2625
|
+
Example::
|
|
2626
|
+
|
|
2627
|
+
fence = xtgeo.polygons_from_file("somefile.pol")
|
|
2628
|
+
fspec = fence.get_fence(distance=20, nextend=5, asnumpy=True)
|
|
2629
|
+
surf = xtgeo.surface_from_file("somefile.gri")
|
|
2630
|
+
|
|
2631
|
+
arr = surf.get_randomline(fspec)
|
|
2632
|
+
|
|
2633
|
+
distance = arr[:, 0]
|
|
2634
|
+
zval = arr[:, 1]
|
|
2635
|
+
# matplotlib...
|
|
2636
|
+
plt.plot(distance, zval)
|
|
2637
|
+
|
|
2638
|
+
.. seealso::
|
|
2639
|
+
Class :class:`~xtgeo.xyz.polygons.Polygons`
|
|
2640
|
+
The method :meth:`~xtgeo.xyz.polygons.Polygons.get_fence()` which can be
|
|
2641
|
+
used to pregenerate `fencespec`
|
|
2642
|
+
"""
|
|
2643
|
+
return _regsurf_oper.get_randomline(
|
|
2644
|
+
self,
|
|
2645
|
+
fencespec,
|
|
2646
|
+
hincrement=hincrement,
|
|
2647
|
+
atleast=atleast,
|
|
2648
|
+
nextend=nextend,
|
|
2649
|
+
sampling=sampling,
|
|
2650
|
+
)
|
|
2651
|
+
|
|
2652
|
+
def hc_thickness_from_3dprops(
|
|
2653
|
+
self,
|
|
2654
|
+
xprop=None,
|
|
2655
|
+
yprop=None,
|
|
2656
|
+
hcpfzprop=None,
|
|
2657
|
+
zoneprop=None,
|
|
2658
|
+
zone_minmax=None,
|
|
2659
|
+
dzprop=None,
|
|
2660
|
+
zone_avg=False,
|
|
2661
|
+
coarsen=1,
|
|
2662
|
+
mask_outside=False,
|
|
2663
|
+
):
|
|
2664
|
+
"""Make a thickness weighted HC thickness map.
|
|
2665
|
+
|
|
2666
|
+
Make a HC thickness map based on numpy arrays of properties
|
|
2667
|
+
from a 3D grid. The numpy arrays here shall be ndarray,
|
|
2668
|
+
not masked numpies (MaskedArray).
|
|
2669
|
+
|
|
2670
|
+
Note that the input hcpfzprop is hydrocarbon fraction multiplied
|
|
2671
|
+
with thickness, which can be achieved by e.g.:
|
|
2672
|
+
cpfz = dz*poro*ntg*shc or by hcpfz = dz*hcpv/vbulk
|
|
2673
|
+
|
|
2674
|
+
Args:
|
|
2675
|
+
xprop (ndarray): 3D numpy array of X coordinates
|
|
2676
|
+
yprop (ndarray): 3D numpy array of Y coordinates
|
|
2677
|
+
hcpfzprop (ndarray): 3D numpy array of HC fraction multiplied
|
|
2678
|
+
with DZ per cell.
|
|
2679
|
+
zoneprop (ndarray): 3D numpy array indicating zonation
|
|
2680
|
+
property, where 1 is the lowest (0 values can be used to
|
|
2681
|
+
exclude parts of the grid)
|
|
2682
|
+
dzprop (ndarray): 3D numpy array holding DZ thickness. Will
|
|
2683
|
+
be applied in weighting if zone_avg is active.
|
|
2684
|
+
zone_minmax (tuple): (optional) 2 element list indicating start
|
|
2685
|
+
and stop zonation (both start and end spec are included)
|
|
2686
|
+
zone_avg (bool): A zone averaging is done prior to map gridding.
|
|
2687
|
+
This may speed up the process a lot, but result will be less
|
|
2688
|
+
precise. Default is False.
|
|
2689
|
+
coarsen (int): Select every N'th X Y point in the gridding. Will
|
|
2690
|
+
speed up process, but less precise result. Default=1
|
|
2691
|
+
mask_outside (bool): Will mask the result map undef where sum of DZ
|
|
2692
|
+
is zero. Default is False as it costs some extra CPU.
|
|
2693
|
+
|
|
2694
|
+
Returns:
|
|
2695
|
+
True if operation went OK (but check result!), False if not
|
|
2696
|
+
"""
|
|
2697
|
+
for inum, myprop in enumerate([xprop, yprop, hcpfzprop, zoneprop]):
|
|
2698
|
+
if isinstance(myprop, ma.MaskedArray):
|
|
2699
|
+
raise ValueError(
|
|
2700
|
+
f"Property input {inum} with avg {myprop.mean()} to {__name__} "
|
|
2701
|
+
"is a masked array, not a plain numpy ndarray"
|
|
2702
|
+
)
|
|
2703
|
+
|
|
2704
|
+
status = _regsurf_gridding.avgsum_from_3dprops_gridding(
|
|
2705
|
+
self,
|
|
2706
|
+
summing=True,
|
|
2707
|
+
xprop=xprop,
|
|
2708
|
+
yprop=yprop,
|
|
2709
|
+
mprop=hcpfzprop,
|
|
2710
|
+
dzprop=dzprop,
|
|
2711
|
+
zoneprop=zoneprop,
|
|
2712
|
+
zone_minmax=zone_minmax,
|
|
2713
|
+
zone_avg=zone_avg,
|
|
2714
|
+
coarsen=coarsen,
|
|
2715
|
+
mask_outside=mask_outside,
|
|
2716
|
+
)
|
|
2717
|
+
|
|
2718
|
+
if status is False:
|
|
2719
|
+
raise RuntimeError("Failure from hc thickness calculation")
|
|
2720
|
+
|
|
2721
|
+
def avg_from_3dprop(
|
|
2722
|
+
self,
|
|
2723
|
+
xprop=None,
|
|
2724
|
+
yprop=None,
|
|
2725
|
+
mprop=None,
|
|
2726
|
+
dzprop=None,
|
|
2727
|
+
truncate_le=None,
|
|
2728
|
+
zoneprop=None,
|
|
2729
|
+
zone_minmax=None,
|
|
2730
|
+
coarsen=1,
|
|
2731
|
+
zone_avg=False,
|
|
2732
|
+
):
|
|
2733
|
+
"""Average map (DZ weighted) based on numpy arrays of properties from a 3D grid.
|
|
2734
|
+
|
|
2735
|
+
The 3D arrays mush be ordinary numpies of size (nx,ny,nz). Undef
|
|
2736
|
+
entries must be given weights 0 by using DZ=0
|
|
2737
|
+
|
|
2738
|
+
Args:
|
|
2739
|
+
xprop: 3D numpy of all X coordinates (also inactive cells)
|
|
2740
|
+
yprop: 3D numpy of all Y coordinates (also inactive cells)
|
|
2741
|
+
mprop: 3D numpy of requested property (e.g. porosity) all
|
|
2742
|
+
dzprop: 3D numpy of dz values (for weighting)
|
|
2743
|
+
NB zero for undef cells
|
|
2744
|
+
truncate_le (float): Optional. Truncate value (mask) if
|
|
2745
|
+
value is less
|
|
2746
|
+
zoneprop: 3D numpy to a zone property
|
|
2747
|
+
zone_minmax: a tuple with from-to zones to combine
|
|
2748
|
+
(e.g. (1,3))
|
|
2749
|
+
|
|
2750
|
+
Returns:
|
|
2751
|
+
Nothing explicit, but updates the surface object.
|
|
2752
|
+
"""
|
|
2753
|
+
for inum, myprop in enumerate([xprop, yprop, mprop, dzprop, zoneprop]):
|
|
2754
|
+
if isinstance(myprop, ma.MaskedArray):
|
|
2755
|
+
raise ValueError(
|
|
2756
|
+
f"Property input {inum} with avg {myprop.mean()} to {__name__} "
|
|
2757
|
+
"is a masked array, not a plain numpy ndarray"
|
|
2758
|
+
)
|
|
2759
|
+
|
|
2760
|
+
_regsurf_gridding.avgsum_from_3dprops_gridding(
|
|
2761
|
+
self,
|
|
2762
|
+
summing=False,
|
|
2763
|
+
xprop=xprop,
|
|
2764
|
+
yprop=yprop,
|
|
2765
|
+
mprop=mprop,
|
|
2766
|
+
dzprop=dzprop,
|
|
2767
|
+
truncate_le=truncate_le,
|
|
2768
|
+
zoneprop=zoneprop,
|
|
2769
|
+
zone_minmax=zone_minmax,
|
|
2770
|
+
coarsen=coarsen,
|
|
2771
|
+
zone_avg=zone_avg,
|
|
2772
|
+
)
|
|
2773
|
+
|
|
2774
|
+
def quickplot(
|
|
2775
|
+
self,
|
|
2776
|
+
filename=None,
|
|
2777
|
+
title="QuickPlot for Surfaces",
|
|
2778
|
+
subtitle=None,
|
|
2779
|
+
infotext=None,
|
|
2780
|
+
minmax=(None, None),
|
|
2781
|
+
xlabelrotation=None,
|
|
2782
|
+
colormap="rainbow",
|
|
2783
|
+
faults=None,
|
|
2784
|
+
logarithmic=False,
|
|
2785
|
+
):
|
|
2786
|
+
"""Fast surface plot of maps using matplotlib.
|
|
2787
|
+
|
|
2788
|
+
Args:
|
|
2789
|
+
filename (str): Name of plot file; None will plot to screen.
|
|
2790
|
+
title (str): Title of plot
|
|
2791
|
+
subtitle (str): Subtitle of plot
|
|
2792
|
+
infotext (str): Additonal info on plot.
|
|
2793
|
+
minmax (tuple): Tuple of min and max values to be plotted. Note
|
|
2794
|
+
that values outside range will be set equal to range limits
|
|
2795
|
+
xlabelrotation (float): Rotation in degrees of X labels.
|
|
2796
|
+
colormap (str): Name of matplotlib or RMS file or XTGeo
|
|
2797
|
+
colormap. Default is matplotlib's 'rainbow'
|
|
2798
|
+
faults (dict): If fault plot is wanted, a dictionary on the
|
|
2799
|
+
form => {'faults': XTGeo Polygons object, 'color': 'k'}
|
|
2800
|
+
logarithmic (bool): If True, a logarithmic contouring color scale
|
|
2801
|
+
will be used.
|
|
2802
|
+
|
|
2803
|
+
"""
|
|
2804
|
+
# This is using the more versatile Map class in XTGeo. Most kwargs
|
|
2805
|
+
# is just passed as is. Prefer using Map() directly in apps?
|
|
2806
|
+
|
|
2807
|
+
ncount = self.values.count()
|
|
2808
|
+
if ncount < 5:
|
|
2809
|
+
xtg.warn(f"None or too few map nodes for plotting. Skip output {filename}!")
|
|
2810
|
+
return
|
|
2811
|
+
|
|
2812
|
+
import xtgeoviz.plot
|
|
2813
|
+
|
|
2814
|
+
mymap = xtgeoviz.plot.Map()
|
|
2815
|
+
|
|
2816
|
+
logger.info("Infotext is <%s>", infotext)
|
|
2817
|
+
mymap.canvas(title=title, subtitle=subtitle, infotext=infotext)
|
|
2818
|
+
|
|
2819
|
+
minvalue = minmax[0]
|
|
2820
|
+
maxvalue = minmax[1]
|
|
2821
|
+
|
|
2822
|
+
mymap.colormap = colormap
|
|
2823
|
+
|
|
2824
|
+
mymap.plot_surface(
|
|
2825
|
+
self,
|
|
2826
|
+
minvalue=minvalue,
|
|
2827
|
+
maxvalue=maxvalue,
|
|
2828
|
+
xlabelrotation=xlabelrotation,
|
|
2829
|
+
logarithmic=logarithmic,
|
|
2830
|
+
)
|
|
2831
|
+
if faults:
|
|
2832
|
+
poly = faults.pop("faults")
|
|
2833
|
+
mymap.plot_faults(poly, **faults)
|
|
2834
|
+
|
|
2835
|
+
if filename is None:
|
|
2836
|
+
mymap.show()
|
|
2837
|
+
else:
|
|
2838
|
+
mymap.savefig(filename)
|
|
2839
|
+
|
|
2840
|
+
def distance_from_point(self, point=(0, 0), azimuth=0.0):
|
|
2841
|
+
"""Make map values as horizontal distance from a point with azimuth direction.
|
|
2842
|
+
|
|
2843
|
+
Args:
|
|
2844
|
+
point (tuple): Point to measure from
|
|
2845
|
+
azimuth (float): Angle from North (clockwise) in degrees
|
|
2846
|
+
|
|
2847
|
+
"""
|
|
2848
|
+
_regsurf_oper.distance_from_point(self, point=point, azimuth=azimuth)
|
|
2849
|
+
|
|
2850
|
+
def translate_coordinates(self, translate=(0, 0, 0)):
|
|
2851
|
+
"""Translate a map in X Y VALUE space.
|
|
2852
|
+
|
|
2853
|
+
Args:
|
|
2854
|
+
translate (tuple): Translate (shift) distance in X Y Z
|
|
2855
|
+
|
|
2856
|
+
Example::
|
|
2857
|
+
|
|
2858
|
+
>>> import xtgeo
|
|
2859
|
+
>>> mysurf = xtgeo.surface_from_file(surface_dir + '/topreek_rota.gri')
|
|
2860
|
+
>>> print(mysurf.xori, mysurf.yori)
|
|
2861
|
+
468895.125 5932889.5
|
|
2862
|
+
>>> mysurf.translate_coordinates((300,500,0))
|
|
2863
|
+
>>> print(mysurf.xori, mysurf.yori)
|
|
2864
|
+
469195.125 5933389.5
|
|
2865
|
+
|
|
2866
|
+
"""
|
|
2867
|
+
xshift, yshift, zshift = translate
|
|
2868
|
+
|
|
2869
|
+
# just shift the xori and yori
|
|
2870
|
+
self.xori = self.xori + xshift
|
|
2871
|
+
self.yori = self.yori + yshift
|
|
2872
|
+
|
|
2873
|
+
# note the Z coordinates are perhaps not depth
|
|
2874
|
+
# numpy operation:
|
|
2875
|
+
self.values = self.values + zshift
|
|
2876
|
+
|
|
2877
|
+
# ==================================================================================
|
|
2878
|
+
# Private
|
|
2879
|
+
# ==================================================================================
|
|
2880
|
+
|
|
2881
|
+
def _ensure_correct_values(
|
|
2882
|
+
self,
|
|
2883
|
+
values,
|
|
2884
|
+
force_dtype=None,
|
|
2885
|
+
):
|
|
2886
|
+
"""Ensures that values is a 2D masked numpy (ncol, nrow), C order.
|
|
2887
|
+
|
|
2888
|
+
This is an improved but private version over ensure_correct_values
|
|
2889
|
+
|
|
2890
|
+
Args:
|
|
2891
|
+
values (array-like or scalar): Values to process.
|
|
2892
|
+
force_dtype (numpy dtype or None): If not None, try to derive dtype from
|
|
2893
|
+
current values
|
|
2894
|
+
|
|
2895
|
+
Return:
|
|
2896
|
+
Nothing, self._values will be updated inplace
|
|
2897
|
+
|
|
2898
|
+
"""
|
|
2899
|
+
apply_dtype = force_dtype if force_dtype else self.dtype
|
|
2900
|
+
|
|
2901
|
+
currentmask = None
|
|
2902
|
+
if isinstance(self.values, ma.MaskedArray):
|
|
2903
|
+
currentmask = ma.getmaskarray(self.values)
|
|
2904
|
+
|
|
2905
|
+
if isinstance(values, ma.MaskedArray):
|
|
2906
|
+
newmask = ma.getmaskarray(values)
|
|
2907
|
+
vals = values.astype(np.float64)
|
|
2908
|
+
vals = ma.masked_greater(vals, self.undef_limit)
|
|
2909
|
+
vals = ma.masked_invalid(vals)
|
|
2910
|
+
if (
|
|
2911
|
+
currentmask is not None
|
|
2912
|
+
and np.array_equal(currentmask, newmask)
|
|
2913
|
+
and self.values.shape == values.shape
|
|
2914
|
+
and values.flags.c_contiguous is True
|
|
2915
|
+
):
|
|
2916
|
+
self._values *= 0
|
|
2917
|
+
self._values += vals
|
|
2918
|
+
else:
|
|
2919
|
+
vals = vals.reshape((self._ncol, self._nrow))
|
|
2920
|
+
if not vals.flags.c_contiguous:
|
|
2921
|
+
mask = ma.getmaskarray(values)
|
|
2922
|
+
mask = np.asanyarray(mask, order="C")
|
|
2923
|
+
vals = np.asanyarray(vals, order="C")
|
|
2924
|
+
vals = ma.array(vals, mask=mask, order="C")
|
|
2925
|
+
self._values = vals
|
|
2926
|
+
|
|
2927
|
+
elif isinstance(values, numbers.Number):
|
|
2928
|
+
if currentmask is not None:
|
|
2929
|
+
vals = np.ones(self.dimensions, dtype=apply_dtype) * values
|
|
2930
|
+
vals = np.ma.array(vals, mask=currentmask)
|
|
2931
|
+
|
|
2932
|
+
# there maybe cases where values scalar input is some kind of UNDEF
|
|
2933
|
+
# which will change the mask
|
|
2934
|
+
vals = ma.masked_greater(vals, self.undef_limit, copy=False)
|
|
2935
|
+
vals = ma.masked_invalid(vals, copy=False)
|
|
2936
|
+
self._values *= 0
|
|
2937
|
+
self._values += vals
|
|
2938
|
+
else:
|
|
2939
|
+
vals = ma.zeros((self.ncol, self.nrow), order="C", dtype=apply_dtype)
|
|
2940
|
+
self._values = vals + float(values)
|
|
2941
|
+
|
|
2942
|
+
elif isinstance(values, (list, tuple, np.ndarray)): # ie values ~ list-like
|
|
2943
|
+
vals = ma.array(values, order="C", dtype=apply_dtype)
|
|
2944
|
+
vals = ma.masked_greater(vals, self.undef_limit, copy=True)
|
|
2945
|
+
vals = ma.masked_invalid(vals, copy=True)
|
|
2946
|
+
|
|
2947
|
+
if vals.shape != (self.ncol, self.nrow):
|
|
2948
|
+
try:
|
|
2949
|
+
vals = ma.reshape(vals, (self.ncol, self.nrow), order="C")
|
|
2950
|
+
except ValueError as emsg:
|
|
2951
|
+
raise ValueError(f"Cannot reshape array: {values}") from emsg
|
|
2952
|
+
|
|
2953
|
+
self._values = vals
|
|
2954
|
+
|
|
2955
|
+
else:
|
|
2956
|
+
raise ValueError(f"Input values are in invalid format: {values}")
|
|
2957
|
+
|
|
2958
|
+
if self._values.mask is ma.nomask:
|
|
2959
|
+
self._values = ma.array(self._values, mask=ma.getmaskarray(self._values))
|
|
2960
|
+
|
|
2961
|
+
# ensure dtype; avoid allocation and ID change if possible by setting copy=False
|
|
2962
|
+
self._values = self._values.astype(apply_dtype, copy=False)
|