or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

file-operations.mdgeometry-operations.mdgravimetry-subsidence.mdgrid-operations.mdindex.mdrft-plt-data.mdsummary-analysis.mdutilities.mdwell-data.md

utilities.mddocs/

0

# Utilities

1

2

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

3

4

## Capabilities

5

6

### Vector Operations

7

8

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

9

10

```python { .api }

11

class IntVector:

12

"""Integer vector operations with dynamic resizing."""

13

14

def __init__(self, initial_size: int = 0, default_value: int = 0):

15

"""

16

Create integer vector.

17

18

Args:

19

initial_size (int): Initial size

20

default_value (int): Default value for new elements

21

"""

22

23

def append(self, value: int):

24

"""Append value to vector."""

25

26

def pop(self) -> int:

27

"""Remove and return last element."""

28

29

def get_max(self) -> int:

30

"""Get maximum value."""

31

32

def get_min(self) -> int:

33

"""Get minimum value."""

34

35

def get_max_index(self) -> int:

36

"""Get index of maximum value."""

37

38

def get_min_index(self) -> int:

39

"""Get index of minimum value."""

40

41

def shift(self, offset: int):

42

"""Shift all values by offset."""

43

44

def scale(self, factor: int):

45

"""Scale all values by factor."""

46

47

def sum(self) -> int:

48

"""Sum all elements."""

49

50

def sort(self):

51

"""Sort in ascending order."""

52

53

def rsort(self):

54

"""Sort in descending order."""

55

56

def safe_get(self, index: int) -> int:

57

"""Get value with bounds checking."""

58

59

def set_default(self, default_value: int):

60

"""Set default value for new elements."""

61

62

def numpy_copy(self) -> numpy.ndarray:

63

"""Get NumPy array copy."""

64

65

class DoubleVector:

66

"""Double precision vector operations."""

67

68

def __init__(self, initial_size: int = 0, default_value: float = 0.0):

69

"""Create double vector."""

70

71

def append(self, value: float):

72

"""Append value to vector."""

73

74

def pop(self) -> float:

75

"""Remove and return last element."""

76

77

def get_max(self) -> float:

78

"""Get maximum value."""

79

80

def get_min(self) -> float:

81

"""Get minimum value."""

82

83

def get_max_index(self) -> int:

84

"""Get index of maximum value."""

85

86

def get_min_index(self) -> int:

87

"""Get index of minimum value."""

88

89

def shift(self, offset: float):

90

"""Shift all values by offset."""

91

92

def scale(self, factor: float):

93

"""Scale all values by factor."""

94

95

def sum(self) -> float:

96

"""Sum all elements."""

97

98

def sort(self):

99

"""Sort in ascending order."""

100

101

def rsort(self):

102

"""Sort in descending order."""

103

104

def safe_get(self, index: int) -> float:

105

"""Get value with bounds checking."""

106

107

def set_default(self, default_value: float):

108

"""Set default value for new elements."""

109

110

def numpy_copy(self) -> numpy.ndarray:

111

"""Get NumPy array copy."""

112

113

class BoolVector:

114

"""Boolean vector operations."""

115

116

def __init__(self, initial_size: int = 0, default_value: bool = False):

117

"""Create boolean vector."""

118

119

def append(self, value: bool):

120

"""Append value to vector."""

121

122

def pop(self) -> bool:

123

"""Remove and return last element."""

124

125

def count_true(self) -> int:

126

"""Count True values."""

127

128

def count_false(self) -> int:

129

"""Count False values."""

130

131

def all_true(self) -> bool:

132

"""Check if all values are True."""

133

134

def any_true(self) -> bool:

135

"""Check if any value is True."""

136

137

def safe_get(self, index: int) -> bool:

138

"""Get value with bounds checking."""

139

140

def set_default(self, default_value: bool):

141

"""Set default value for new elements."""

142

143

def numpy_copy(self) -> numpy.ndarray:

144

"""Get NumPy array copy."""

145

```

146

147

### Time Vector Operations

148

149

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

150

151

```python { .api }

152

class TimeVector:

153

"""Time vector operations for datetime data."""

154

155

def __init__(self):

156

"""Create time vector."""

157

158

def append(self, time: datetime):

159

"""Append datetime to vector."""

160

161

def get_data_ptr(self) -> list:

162

"""Get internal data pointer."""

163

164

def active_list(self) -> list:

165

"""Get list of active time points."""

166

167

def select_matching(self, pattern: str) -> BoolVector:

168

"""Select times matching pattern."""

169

170

def get_active_mask(self) -> BoolVector:

171

"""Get mask of active time points."""

172

```

173

174

### String Operations

175

176

String list container with search and manipulation capabilities.

177

178

```python { .api }

179

class StringList:

180

"""String list operations and management."""

181

182

def __init__(self):

183

"""Create empty string list."""

184

185

def append(self, string: str):

186

"""Append string to list."""

187

188

def get_last(self) -> str:

189

"""Get last string."""

190

191

def pop(self) -> str:

192

"""Remove and return last string."""

193

194

def sort(self):

195

"""Sort strings alphabetically."""

196

197

def contains(self, string: str) -> bool:

198

"""Check if string is in list."""

199

200

def find_first(self, string: str) -> int:

201

"""Find first occurrence index."""

202

203

def size(self) -> int:

204

"""Get number of strings."""

205

```

206

207

### Hash Table Operations

208

209

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

210

211

```python { .api }

212

class Hash:

213

"""Generic hash table operations."""

214

215

def __init__(self):

216

"""Create empty hash table."""

217

218

def insert(self, key: str, value):

219

"""Insert key-value pair."""

220

221

def get(self, key: str):

222

"""Get value by key."""

223

224

def has_key(self, key: str) -> bool:

225

"""Check if key exists."""

226

227

def keys(self) -> list:

228

"""Get list of keys."""

229

230

def values(self) -> list:

231

"""Get list of values."""

232

233

def clear(self):

234

"""Clear all entries."""

235

236

def size(self) -> int:

237

"""Get number of entries."""

238

239

class StringHash(Hash):

240

"""String-specific hash table."""

241

242

def insert(self, key: str, value: str):

243

"""Insert string key-value pair."""

244

245

def get(self, key: str) -> str:

246

"""Get string value by key."""

247

248

class IntegerHash(Hash):

249

"""Integer-specific hash table."""

250

251

def insert(self, key: str, value: int):

252

"""Insert integer key-value pair."""

253

254

def get(self, key: str) -> int:

255

"""Get integer value by key."""

256

257

class DoubleHash(Hash):

258

"""Double-specific hash table."""

259

260

def insert(self, key: str, value: float):

261

"""Insert double key-value pair."""

262

263

def get(self, key: str) -> float:

264

"""Get double value by key."""

265

```

266

267

### Time Handling

268

269

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

270

271

```python { .api }

272

class CTime:

273

"""C-based time handling and operations."""

274

275

def __init__(self, time_input=None):

276

"""

277

Create CTime object.

278

279

Args:

280

time_input: datetime, timestamp, or None for current time

281

"""

282

283

def datetime(self) -> datetime:

284

"""Convert to Python datetime."""

285

286

def ctime(self) -> str:

287

"""Get C-style time string."""

288

289

def stripped_copy(self) -> CTime:

290

"""Create copy with stripped time components."""

291

292

def set_date(self, year: int, month: int, day: int):

293

"""Set date components."""

294

295

def date(self) -> tuple:

296

"""Get (year, month, day) tuple."""

297

298

def year(self) -> int:

299

"""Get year."""

300

301

def month(self) -> int:

302

"""Get month."""

303

304

def mday(self) -> int:

305

"""Get day of month."""

306

```

307

308

### Permutation Operations

309

310

Permutation vector for sorting and reordering operations.

311

312

```python { .api }

313

class PermutationVector:

314

"""Permutation operations for data reordering."""

315

316

def __init__(self, size: int):

317

"""Create permutation vector."""

318

319

def sort_vector(self, data_vector):

320

"""Sort vector using permutation."""

321

322

def permute_vector(self, data_vector):

323

"""Apply permutation to vector."""

324

```

325

326

### Random Number Generation

327

328

High-quality random number generation with multiple algorithms.

329

330

```python { .api }

331

class RandomNumberGenerator:

332

"""Random number generation with configurable algorithms."""

333

334

def __init__(self, algorithm: RngAlgTypeEnum = RngAlgTypeEnum.MZRAN,

335

init_mode: RngInitModeEnum = RngInitModeEnum.INIT_DEFAULT):

336

"""

337

Create random number generator.

338

339

Args:

340

algorithm: RNG algorithm type

341

init_mode: Initialization mode

342

"""

343

344

def get_double(self) -> float:

345

"""Get random double [0, 1)."""

346

347

def get_int(self, max_value: int) -> int:

348

"""Get random integer [0, max_value)."""

349

350

def seed(self, seed_value: int):

351

"""Set random seed."""

352

353

def state_size(self) -> int:

354

"""Get state size in bytes."""

355

```

356

357

### Lookup Tables

358

359

Lookup table operations for interpolation and data mapping.

360

361

```python { .api }

362

class LookupTable:

363

"""Lookup table for interpolation and mapping."""

364

365

def __init__(self):

366

"""Create empty lookup table."""

367

368

def append(self, x: float, y: float):

369

"""Add (x, y) point to table."""

370

371

def get_value(self, x: float) -> float:

372

"""Get interpolated value at x."""

373

374

def has_key(self, x: float) -> bool:

375

"""Check if exact key exists."""

376

377

def size(self) -> int:

378

"""Get number of points."""

379

380

def get_min_arg(self) -> float:

381

"""Get minimum x value."""

382

383

def get_max_arg(self) -> float:

384

"""Get maximum x value."""

385

```

386

387

### Version Information

388

389

Version and build information access.

390

391

```python { .api }

392

class ResdataVersion:

393

"""ResData version and build information."""

394

395

@staticmethod

396

def versionString() -> str:

397

"""Get version string."""

398

399

@staticmethod

400

def versionTuple() -> tuple:

401

"""Get version tuple (major, minor, patch)."""

402

403

@staticmethod

404

def isDevelVersion() -> bool:

405

"""Check if development version."""

406

407

@staticmethod

408

def getGitCommit() -> str:

409

"""Get git commit hash."""

410

411

@staticmethod

412

def getBuildTime() -> str:

413

"""Get build timestamp."""

414

```

415

416

### Context Management

417

418

Context managers for working directory and other state management.

419

420

```python { .api }

421

class CWDContext:

422

"""Context manager for working directory changes."""

423

424

def __init__(self, path: str):

425

"""

426

Create working directory context.

427

428

Args:

429

path (str): Target directory path

430

"""

431

432

def __enter__(self):

433

"""Enter context and change directory."""

434

return self

435

436

def __exit__(self, exc_type, exc_val, exc_tb):

437

"""Exit context and restore directory."""

438

```

439

440

## Usage Examples

441

442

### Vector Operations

443

444

```python

445

from resdata.util import IntVector, DoubleVector, BoolVector

446

import numpy as np

447

448

# Create and populate integer vector

449

int_vec = IntVector()

450

for i in range(10):

451

int_vec.append(i * i) # Square numbers

452

453

print(f"Integer vector size: {int_vec.size()}")

454

print(f"Max value: {int_vec.get_max()}")

455

print(f"Min value: {int_vec.get_min()}")

456

print(f"Sum: {int_vec.sum()}")

457

458

# Convert to NumPy for advanced operations

459

int_array = int_vec.numpy_copy()

460

print(f"NumPy array: {int_array}")

461

print(f"Mean: {np.mean(int_array):.2f}")

462

463

# Double vector operations

464

double_vec = DoubleVector(5, 1.0) # Size 5, default value 1.0

465

double_vec.scale(2.5) # Scale all values

466

double_vec.shift(10.0) # Add offset

467

468

# Boolean vector for masking

469

bool_vec = BoolVector()

470

for val in int_array:

471

bool_vec.append(val > 25) # Values greater than 25

472

473

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

474

```

475

476

### Hash Table Usage

477

478

```python

479

from resdata.util import StringHash, DoubleHash

480

481

# String mapping

482

well_types = StringHash()

483

well_types.insert("PROD01", "Producer")

484

well_types.insert("INJ01", "Water Injector")

485

well_types.insert("INJ02", "Gas Injector")

486

487

print("Well Types:")

488

for key in well_types.keys():

489

print(f" {key}: {well_types.get(key)}")

490

491

# Numerical properties

492

well_rates = DoubleHash()

493

well_rates.insert("PROD01", 150.5)

494

well_rates.insert("PROD02", 89.2)

495

well_rates.insert("PROD03", 234.7)

496

497

# Find maximum rate

498

max_rate = 0.0

499

max_well = ""

500

for key in well_rates.keys():

501

rate = well_rates.get(key)

502

if rate > max_rate:

503

max_rate = rate

504

max_well = key

505

506

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

507

```

508

509

### Time Operations

510

511

```python

512

from resdata.util import CTime, TimeVector

513

from datetime import datetime, timedelta

514

515

# Create time objects

516

start_time = CTime(datetime(2020, 1, 1))

517

current_time = CTime() # Current time

518

519

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

520

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

521

522

# Work with time components

523

year = start_time.year()

524

month = start_time.month()

525

day = start_time.mday()

526

print(f"Start date components: {year}-{month:02d}-{day:02d}")

527

528

# Time vector for series data

529

time_series = TimeVector()

530

base_date = datetime(2020, 1, 1)

531

for i in range(12):

532

month_date = base_date + timedelta(days=30*i)

533

time_series.append(month_date)

534

535

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

536

```

537

538

### Lookup Table Operations

539

540

```python

541

from resdata.util import LookupTable

542

import numpy as np

543

544

# Create pressure-depth relationship

545

pressure_depth = LookupTable()

546

547

# Add data points (depth in meters, pressure in bar)

548

depths = [0, 500, 1000, 1500, 2000, 2500, 3000]

549

pressures = [1, 51, 101, 151, 201, 251, 301] # Hydrostatic + formation pressure

550

551

for depth, pressure in zip(depths, pressures):

552

pressure_depth.append(depth, pressure)

553

554

print(f"Lookup table size: {pressure_depth.size()}")

555

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

556

557

# Interpolate pressures

558

test_depths = [750, 1250, 2750]

559

for depth in test_depths:

560

pressure = pressure_depth.get_value(depth)

561

print(f"Pressure at {depth}m: {pressure:.1f} bar")

562

```

563

564

### Random Number Generation

565

566

```python

567

from resdata.util import RandomNumberGenerator, RngAlgTypeEnum

568

import numpy as np

569

570

# Create random number generator

571

rng = RandomNumberGenerator(RngAlgTypeEnum.MZRAN)

572

rng.seed(42) # Set seed for reproducibility

573

574

# Generate random data

575

random_doubles = [rng.get_double() for _ in range(1000)]

576

random_ints = [rng.get_int(100) for _ in range(1000)]

577

578

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

579

print(f"Random ints: min={min(random_ints)}, max={max(random_ints)}")

580

581

# Statistical analysis

582

doubles_array = np.array(random_doubles)

583

print(f"Mean: {np.mean(doubles_array):.3f}")

584

print(f"Std dev: {np.std(doubles_array):.3f}")

585

586

# Generate normally distributed values (Box-Muller transform)

587

normal_values = []

588

for i in range(0, 1000, 2):

589

u1 = rng.get_double()

590

u2 = rng.get_double()

591

592

# Box-Muller transform

593

z1 = np.sqrt(-2 * np.log(u1)) * np.cos(2 * np.pi * u2)

594

z2 = np.sqrt(-2 * np.log(u1)) * np.sin(2 * np.pi * u2)

595

596

normal_values.extend([z1, z2])

597

598

normal_array = np.array(normal_values[:1000])

599

print(f"Normal distribution: mean={np.mean(normal_array):.3f}, std={np.std(normal_array):.3f}")

600

```

601

602

### Working Directory Context

603

604

```python

605

from resdata.util import CWDContext

606

import os

607

608

# Get current directory

609

original_dir = os.getcwd()

610

print(f"Original directory: {original_dir}")

611

612

# Use context manager to change directory

613

target_dir = "/tmp"

614

with CWDContext(target_dir):

615

current_dir = os.getcwd()

616

print(f"Inside context: {current_dir}")

617

618

# Do work in target directory

619

# Files created here will be in target_dir

620

621

# Back to original directory

622

final_dir = os.getcwd()

623

print(f"After context: {final_dir}")

624

assert final_dir == original_dir, "Directory not restored!"

625

```

626

627

### Version Information

628

629

```python

630

from resdata.util import ResdataVersion

631

632

# Get version information

633

version_str = ResdataVersion.versionString()

634

version_tuple = ResdataVersion.versionTuple()

635

is_devel = ResdataVersion.isDevelVersion()

636

git_commit = ResdataVersion.getGitCommit()

637

build_time = ResdataVersion.getBuildTime()

638

639

print(f"ResData Version: {version_str}")

640

print(f"Version tuple: {version_tuple}")

641

print(f"Development version: {is_devel}")

642

print(f"Git commit: {git_commit}")

643

print(f"Build time: {build_time}")

644

645

# Version comparison

646

major, minor, patch = version_tuple

647

if major >= 5 and minor >= 1:

648

print("Using ResData 5.1+ features")

649

else:

650

print("Consider upgrading ResData for latest features")

651

```

652

653

## Types

654

655

```python { .api }

656

# Random number generator enums

657

RngAlgTypeEnum = Literal[

658

"MZRAN", # Marsaglia-Zaman random number generator

659

"RANLUX", # RANLUX generator

660

"TAUS" # Tausworthe generator

661

]

662

663

RngInitModeEnum = Literal[

664

"INIT_DEFAULT", # Default initialization

665

"INIT_CLOCK", # Initialize from system clock

666

"INIT_DEV_RANDOM" # Initialize from /dev/random

667

]

668

669

# Version tuple type

670

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

671

672

# Hash table key-value types

673

HashKeyValue = dict[str, any] # Generic hash contents

674

StringHashContents = dict[str, str]

675

IntegerHashContents = dict[str, int]

676

DoubleHashContents = dict[str, float]

677

```