CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-resdata

Python package for reading and writing reservoir simulator result files including RESTART, INIT, RFT, Summary and GRID files in various formats.

Pending
Overview
Eval results
Files

utilities.mddocs/

Utilities

Comprehensive utility classes and functions supporting core ResData functionality including vector operations, time handling, random number generation, data type management, and testing utilities.

Capabilities

Vector Operations

Type-specific vector classes providing high-performance array operations with seamless NumPy integration.

class IntVector:
    """Integer vector operations with dynamic resizing."""
    
    def __init__(self, initial_size: int = 0, default_value: int = 0):
        """
        Create integer vector.
        
        Args:
            initial_size (int): Initial size
            default_value (int): Default value for new elements
        """
    
    def append(self, value: int):
        """Append value to vector."""
    
    def pop(self) -> int:
        """Remove and return last element."""
    
    def get_max(self) -> int:
        """Get maximum value."""
    
    def get_min(self) -> int:
        """Get minimum value."""
    
    def get_max_index(self) -> int:
        """Get index of maximum value."""
    
    def get_min_index(self) -> int:
        """Get index of minimum value."""
    
    def shift(self, offset: int):
        """Shift all values by offset."""
    
    def scale(self, factor: int):
        """Scale all values by factor."""
    
    def sum(self) -> int:
        """Sum all elements."""
    
    def sort(self):
        """Sort in ascending order."""
    
    def rsort(self):
        """Sort in descending order."""
    
    def safe_get(self, index: int) -> int:
        """Get value with bounds checking."""
    
    def set_default(self, default_value: int):
        """Set default value for new elements."""
    
    def numpy_copy(self) -> numpy.ndarray:
        """Get NumPy array copy."""

class DoubleVector:
    """Double precision vector operations."""
    
    def __init__(self, initial_size: int = 0, default_value: float = 0.0):
        """Create double vector."""
    
    def append(self, value: float):
        """Append value to vector."""
    
    def pop(self) -> float:
        """Remove and return last element."""
    
    def get_max(self) -> float:
        """Get maximum value."""
    
    def get_min(self) -> float:
        """Get minimum value."""
    
    def get_max_index(self) -> int:
        """Get index of maximum value."""
    
    def get_min_index(self) -> int:
        """Get index of minimum value."""
    
    def shift(self, offset: float):
        """Shift all values by offset."""
    
    def scale(self, factor: float):
        """Scale all values by factor."""
    
    def sum(self) -> float:
        """Sum all elements."""
    
    def sort(self):
        """Sort in ascending order."""
    
    def rsort(self):
        """Sort in descending order."""
    
    def safe_get(self, index: int) -> float:
        """Get value with bounds checking."""
    
    def set_default(self, default_value: float):
        """Set default value for new elements."""
    
    def numpy_copy(self) -> numpy.ndarray:
        """Get NumPy array copy."""

class BoolVector:
    """Boolean vector operations."""
    
    def __init__(self, initial_size: int = 0, default_value: bool = False):
        """Create boolean vector."""
    
    def append(self, value: bool):
        """Append value to vector."""
    
    def pop(self) -> bool:
        """Remove and return last element."""
    
    def count_true(self) -> int:
        """Count True values."""
    
    def count_false(self) -> int:  
        """Count False values."""
    
    def all_true(self) -> bool:
        """Check if all values are True."""
    
    def any_true(self) -> bool:
        """Check if any value is True."""
    
    def safe_get(self, index: int) -> bool:
        """Get value with bounds checking."""
    
    def set_default(self, default_value: bool):
        """Set default value for new elements."""
    
    def numpy_copy(self) -> numpy.ndarray:
        """Get NumPy array copy."""

Time Vector Operations

Specialized vector for time-based data with date/time functionality.

class TimeVector:
    """Time vector operations for datetime data."""
    
    def __init__(self):
        """Create time vector."""
    
    def append(self, time: datetime):
        """Append datetime to vector."""
    
    def get_data_ptr(self) -> list:
        """Get internal data pointer."""
    
    def active_list(self) -> list:
        """Get list of active time points."""
    
    def select_matching(self, pattern: str) -> BoolVector:
        """Select times matching pattern."""
    
    def get_active_mask(self) -> BoolVector:
        """Get mask of active time points."""

String Operations

String list container with search and manipulation capabilities.

class StringList:
    """String list operations and management."""
    
    def __init__(self):
        """Create empty string list."""
    
    def append(self, string: str):
        """Append string to list."""
    
    def get_last(self) -> str:
        """Get last string."""
    
    def pop(self) -> str:
        """Remove and return last string."""
    
    def sort(self):
        """Sort strings alphabetically."""
    
    def contains(self, string: str) -> bool:
        """Check if string is in list."""
    
    def find_first(self, string: str) -> int:
        """Find first occurrence index."""
    
    def size(self) -> int:
        """Get number of strings."""

Hash Table Operations

Hash table implementations for different data types with key-value storage.

class Hash:
    """Generic hash table operations."""
    
    def __init__(self):
        """Create empty hash table."""
    
    def insert(self, key: str, value):
        """Insert key-value pair."""
    
    def get(self, key: str):
        """Get value by key."""
    
    def has_key(self, key: str) -> bool:
        """Check if key exists."""
    
    def keys(self) -> list:
        """Get list of keys."""
    
    def values(self) -> list:
        """Get list of values."""
    
    def clear(self):
        """Clear all entries."""
    
    def size(self) -> int:
        """Get number of entries."""

class StringHash(Hash):
    """String-specific hash table."""
    
    def insert(self, key: str, value: str):
        """Insert string key-value pair."""
    
    def get(self, key: str) -> str:
        """Get string value by key."""

class IntegerHash(Hash):
    """Integer-specific hash table."""
    
    def insert(self, key: str, value: int):
        """Insert integer key-value pair."""
    
    def get(self, key: str) -> int:
        """Get integer value by key."""

class DoubleHash(Hash):
    """Double-specific hash table."""
    
    def insert(self, key: str, value: float):
        """Insert double key-value pair."""
    
    def get(self, key: str) -> float:
        """Get double value by key."""

Time Handling

C-based time operations providing high-performance datetime functionality.

class CTime:
    """C-based time handling and operations."""
    
    def __init__(self, time_input=None):
        """
        Create CTime object.
        
        Args:
            time_input: datetime, timestamp, or None for current time
        """
    
    def datetime(self) -> datetime:
        """Convert to Python datetime."""
    
    def ctime(self) -> str:
        """Get C-style time string."""
    
    def stripped_copy(self) -> CTime:
        """Create copy with stripped time components."""
    
    def set_date(self, year: int, month: int, day: int):
        """Set date components."""
    
    def date(self) -> tuple:
        """Get (year, month, day) tuple."""
    
    def year(self) -> int:
        """Get year."""
    
    def month(self) -> int:
        """Get month."""
    
    def mday(self) -> int:
        """Get day of month."""

Permutation Operations

Permutation vector for sorting and reordering operations.

class PermutationVector:
    """Permutation operations for data reordering."""
    
    def __init__(self, size: int):
        """Create permutation vector."""
    
    def sort_vector(self, data_vector):
        """Sort vector using permutation."""
    
    def permute_vector(self, data_vector):
        """Apply permutation to vector."""

Random Number Generation

High-quality random number generation with multiple algorithms.

class RandomNumberGenerator:
    """Random number generation with configurable algorithms."""
    
    def __init__(self, algorithm: RngAlgTypeEnum = RngAlgTypeEnum.MZRAN, 
                 init_mode: RngInitModeEnum = RngInitModeEnum.INIT_DEFAULT):
        """
        Create random number generator.
        
        Args:
            algorithm: RNG algorithm type
            init_mode: Initialization mode
        """
    
    def get_double(self) -> float:
        """Get random double [0, 1)."""
    
    def get_int(self, max_value: int) -> int:
        """Get random integer [0, max_value)."""
    
    def seed(self, seed_value: int):
        """Set random seed."""
    
    def state_size(self) -> int:
        """Get state size in bytes."""

Lookup Tables

Lookup table operations for interpolation and data mapping.

class LookupTable:
    """Lookup table for interpolation and mapping."""
    
    def __init__(self):
        """Create empty lookup table."""
    
    def append(self, x: float, y: float):
        """Add (x, y) point to table."""
    
    def get_value(self, x: float) -> float:
        """Get interpolated value at x."""
    
    def has_key(self, x: float) -> bool:
        """Check if exact key exists."""
    
    def size(self) -> int:
        """Get number of points."""
    
    def get_min_arg(self) -> float:
        """Get minimum x value."""
    
    def get_max_arg(self) -> float:
        """Get maximum x value."""

Version Information

Version and build information access.

class ResdataVersion:
    """ResData version and build information."""
    
    @staticmethod
    def versionString() -> str:
        """Get version string."""
    
    @staticmethod
    def versionTuple() -> tuple:
        """Get version tuple (major, minor, patch)."""
    
    @staticmethod
    def isDevelVersion() -> bool:
        """Check if development version."""
    
    @staticmethod
    def getGitCommit() -> str:
        """Get git commit hash."""
    
    @staticmethod
    def getBuildTime() -> str:
        """Get build timestamp."""

Context Management

Context managers for working directory and other state management.

class CWDContext:
    """Context manager for working directory changes."""
    
    def __init__(self, path: str):
        """
        Create working directory context.
        
        Args:
            path (str): Target directory path
        """
    
    def __enter__(self):
        """Enter context and change directory."""
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """Exit context and restore directory."""

Usage Examples

Vector Operations

from resdata.util import IntVector, DoubleVector, BoolVector
import numpy as np

# Create and populate integer vector
int_vec = IntVector()
for i in range(10):
    int_vec.append(i * i)  # Square numbers

print(f"Integer vector size: {int_vec.size()}")
print(f"Max value: {int_vec.get_max()}")
print(f"Min value: {int_vec.get_min()}")
print(f"Sum: {int_vec.sum()}")

# Convert to NumPy for advanced operations
int_array = int_vec.numpy_copy()
print(f"NumPy array: {int_array}")
print(f"Mean: {np.mean(int_array):.2f}")

# Double vector operations
double_vec = DoubleVector(5, 1.0)  # Size 5, default value 1.0
double_vec.scale(2.5)  # Scale all values
double_vec.shift(10.0)  # Add offset

# Boolean vector for masking
bool_vec = BoolVector()
for val in int_array:
    bool_vec.append(val > 25)  # Values greater than 25

print(f"Values > 25: {bool_vec.count_true()}/{bool_vec.size()}")

Hash Table Usage

from resdata.util import StringHash, DoubleHash

# String mapping
well_types = StringHash()
well_types.insert("PROD01", "Producer")
well_types.insert("INJ01", "Water Injector")
well_types.insert("INJ02", "Gas Injector")

print("Well Types:")
for key in well_types.keys():
    print(f"  {key}: {well_types.get(key)}")

# Numerical properties
well_rates = DoubleHash()
well_rates.insert("PROD01", 150.5)
well_rates.insert("PROD02", 89.2)
well_rates.insert("PROD03", 234.7)

# Find maximum rate
max_rate = 0.0
max_well = ""
for key in well_rates.keys():
    rate = well_rates.get(key)
    if rate > max_rate:
        max_rate = rate
        max_well = key

print(f"Highest rate: {max_well} at {max_rate} m³/day")

Time Operations

from resdata.util import CTime, TimeVector
from datetime import datetime, timedelta

# Create time objects
start_time = CTime(datetime(2020, 1, 1))
current_time = CTime()  # Current time

print(f"Start date: {start_time.datetime()}")
print(f"Current time: {current_time.datetime()}")

# Work with time components
year = start_time.year()
month = start_time.month()
day = start_time.mday()
print(f"Start date components: {year}-{month:02d}-{day:02d}")

# Time vector for series data
time_series = TimeVector()
base_date = datetime(2020, 1, 1)
for i in range(12):
    month_date = base_date + timedelta(days=30*i)
    time_series.append(month_date)

print(f"Time series length: {len(time_series.active_list())}")

Lookup Table Operations

from resdata.util import LookupTable
import numpy as np

# Create pressure-depth relationship
pressure_depth = LookupTable()

# Add data points (depth in meters, pressure in bar)
depths = [0, 500, 1000, 1500, 2000, 2500, 3000]
pressures = [1, 51, 101, 151, 201, 251, 301]  # Hydrostatic + formation pressure

for depth, pressure in zip(depths, pressures):
    pressure_depth.append(depth, pressure)

print(f"Lookup table size: {pressure_depth.size()}")
print(f"Depth range: {pressure_depth.get_min_arg():.0f} - {pressure_depth.get_max_arg():.0f} m")

# Interpolate pressures
test_depths = [750, 1250, 2750]
for depth in test_depths:
    pressure = pressure_depth.get_value(depth)
    print(f"Pressure at {depth}m: {pressure:.1f} bar")

Random Number Generation

from resdata.util import RandomNumberGenerator, RngAlgTypeEnum
import numpy as np

# Create random number generator
rng = RandomNumberGenerator(RngAlgTypeEnum.MZRAN)
rng.seed(42)  # Set seed for reproducibility

# Generate random data
random_doubles = [rng.get_double() for _ in range(1000)]
random_ints = [rng.get_int(100) for _ in range(1000)]

print(f"Random doubles: min={min(random_doubles):.3f}, max={max(random_doubles):.3f}")
print(f"Random ints: min={min(random_ints)}, max={max(random_ints)}")

# Statistical analysis
doubles_array = np.array(random_doubles)
print(f"Mean: {np.mean(doubles_array):.3f}")
print(f"Std dev: {np.std(doubles_array):.3f}")

# Generate normally distributed values (Box-Muller transform)
normal_values = []
for i in range(0, 1000, 2):
    u1 = rng.get_double()
    u2 = rng.get_double()
    
    # Box-Muller transform
    z1 = np.sqrt(-2 * np.log(u1)) * np.cos(2 * np.pi * u2)
    z2 = np.sqrt(-2 * np.log(u1)) * np.sin(2 * np.pi * u2)
    
    normal_values.extend([z1, z2])

normal_array = np.array(normal_values[:1000])
print(f"Normal distribution: mean={np.mean(normal_array):.3f}, std={np.std(normal_array):.3f}")

Working Directory Context

from resdata.util import CWDContext
import os

# Get current directory
original_dir = os.getcwd()
print(f"Original directory: {original_dir}")

# Use context manager to change directory
target_dir = "/tmp"
with CWDContext(target_dir):
    current_dir = os.getcwd()
    print(f"Inside context: {current_dir}")
    
    # Do work in target directory
    # Files created here will be in target_dir

# Back to original directory
final_dir = os.getcwd()
print(f"After context: {final_dir}")
assert final_dir == original_dir, "Directory not restored!"

Version Information

from resdata.util import ResdataVersion

# Get version information
version_str = ResdataVersion.versionString()
version_tuple = ResdataVersion.versionTuple()
is_devel = ResdataVersion.isDevelVersion()
git_commit = ResdataVersion.getGitCommit()
build_time = ResdataVersion.getBuildTime()

print(f"ResData Version: {version_str}")
print(f"Version tuple: {version_tuple}")
print(f"Development version: {is_devel}")
print(f"Git commit: {git_commit}")
print(f"Build time: {build_time}")

# Version comparison
major, minor, patch = version_tuple
if major >= 5 and minor >= 1:
    print("Using ResData 5.1+ features")
else:
    print("Consider upgrading ResData for latest features")

Types

# Random number generator enums
RngAlgTypeEnum = Literal[
    "MZRAN",     # Marsaglia-Zaman random number generator
    "RANLUX",    # RANLUX generator
    "TAUS"       # Tausworthe generator
]

RngInitModeEnum = Literal[
    "INIT_DEFAULT",  # Default initialization
    "INIT_CLOCK",    # Initialize from system clock
    "INIT_DEV_RANDOM" # Initialize from /dev/random
]

# Version tuple type
VersionTuple = tuple[int, int, int]  # (major, minor, patch)

# Hash table key-value types
HashKeyValue = dict[str, any]  # Generic hash contents
StringHashContents = dict[str, str]
IntegerHashContents = dict[str, int]
DoubleHashContents = dict[str, float]

Install with Tessl CLI

npx tessl i tessl/pypi-resdata

docs

file-operations.md

geometry-operations.md

gravimetry-subsidence.md

grid-operations.md

index.md

rft-plt-data.md

summary-analysis.md

utilities.md

well-data.md

tile.json