well-log-toolkit 0.1.137__tar.gz → 0.1.139__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/PKG-INFO +14 -10
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/README.md +13 -9
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/pyproject.toml +1 -1
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/manager.py +41 -19
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/property.py +6 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/visualization.py +38 -52
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit.egg-info/PKG-INFO +14 -10
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/setup.cfg +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/__init__.py +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/exceptions.py +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/las_file.py +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/operations.py +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/regression.py +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/statistics.py +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/utils.py +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit/well.py +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit.egg-info/SOURCES.txt +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit.egg-info/dependency_links.txt +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit.egg-info/requires.txt +0 -0
- {well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: well-log-toolkit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.139
|
|
4
4
|
Summary: Fast LAS file processing with lazy loading and filtering for well log analysis
|
|
5
5
|
Author-email: Kristian dF Kollsgård <kkollsg@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -463,7 +463,10 @@ template.add_track(track_type="continuous", logs=[...], title="Resistivity")
|
|
|
463
463
|
template.add_track(track_type="discrete", logs=[...], title="Facies")
|
|
464
464
|
template.add_track(track_type="depth", width=0.3, title="Depth")
|
|
465
465
|
|
|
466
|
-
#
|
|
466
|
+
# Add to project (saves with manager.save())
|
|
467
|
+
manager.add_template(template) # Uses template name "reservoir"
|
|
468
|
+
|
|
469
|
+
# Or save standalone file
|
|
467
470
|
template.save("reservoir_template.json")
|
|
468
471
|
```
|
|
469
472
|
|
|
@@ -811,8 +814,8 @@ view.show()
|
|
|
811
814
|
|
|
812
815
|
**Option 2: Store in manager (recommended for multi-well projects)**
|
|
813
816
|
```python
|
|
814
|
-
# Store template in manager
|
|
815
|
-
manager.
|
|
817
|
+
# Store template in manager (uses template.name automatically)
|
|
818
|
+
manager.add_template(template)
|
|
816
819
|
|
|
817
820
|
# Use by name in any well
|
|
818
821
|
view = well.WellView(depth_range=[2800, 3000], template="reservoir")
|
|
@@ -859,8 +862,8 @@ template.remove_track(2)
|
|
|
859
862
|
template.add_track(track_type="continuous", logs=[{"name": "RT"}])
|
|
860
863
|
|
|
861
864
|
# Save changes
|
|
862
|
-
manager.
|
|
863
|
-
template.save("updated_template.json")
|
|
865
|
+
manager.add_template(template) # Update in manager (uses template.name)
|
|
866
|
+
template.save("updated_template.json") # Save to file
|
|
864
867
|
```
|
|
865
868
|
|
|
866
869
|
### Customization
|
|
@@ -1006,8 +1009,8 @@ template.add_track(track_type="depth", width=0.3, title="MD (m)")
|
|
|
1006
1009
|
# Add formation tops spanning all tracks
|
|
1007
1010
|
template.add_tops(property_name='Zone')
|
|
1008
1011
|
|
|
1009
|
-
#
|
|
1010
|
-
manager.
|
|
1012
|
+
# Add to project and display
|
|
1013
|
+
manager.add_template(template)
|
|
1011
1014
|
view = well.WellView(depth_range=[2800, 3200], template="comprehensive")
|
|
1012
1015
|
view.save("comprehensive_log.png", dpi=300)
|
|
1013
1016
|
```
|
|
@@ -1886,7 +1889,8 @@ from well_log_toolkit import WellDataManager, Well, Property, LasFile
|
|
|
1886
1889
|
- `remove_well(name)` - Remove well
|
|
1887
1890
|
- `save(directory)` - Save project
|
|
1888
1891
|
- `load(directory)` - Load project
|
|
1889
|
-
- `
|
|
1892
|
+
- `add_template(template)` - Store template (uses template.name)
|
|
1893
|
+
- `set_template(name, template)` - Store template with custom name
|
|
1890
1894
|
- `get_template(name)` - Retrieve template
|
|
1891
1895
|
- `list_templates()` - List template names
|
|
1892
1896
|
- `Crossplot(x, y, wells=None, shape="well", ...)` - Create multi-well crossplot
|
|
@@ -2053,7 +2057,7 @@ template.add_track(
|
|
|
2053
2057
|
logs=[{"name": "GR", "x_range": [0, 150], "color": "green"}],
|
|
2054
2058
|
title="Gamma Ray"
|
|
2055
2059
|
)
|
|
2056
|
-
manager.
|
|
2060
|
+
manager.add_template(template) # Stored as "custom"
|
|
2057
2061
|
view = well.WellView(template="custom")
|
|
2058
2062
|
view.save("log.png", dpi=300)
|
|
2059
2063
|
```
|
|
@@ -425,7 +425,10 @@ template.add_track(track_type="continuous", logs=[...], title="Resistivity")
|
|
|
425
425
|
template.add_track(track_type="discrete", logs=[...], title="Facies")
|
|
426
426
|
template.add_track(track_type="depth", width=0.3, title="Depth")
|
|
427
427
|
|
|
428
|
-
#
|
|
428
|
+
# Add to project (saves with manager.save())
|
|
429
|
+
manager.add_template(template) # Uses template name "reservoir"
|
|
430
|
+
|
|
431
|
+
# Or save standalone file
|
|
429
432
|
template.save("reservoir_template.json")
|
|
430
433
|
```
|
|
431
434
|
|
|
@@ -773,8 +776,8 @@ view.show()
|
|
|
773
776
|
|
|
774
777
|
**Option 2: Store in manager (recommended for multi-well projects)**
|
|
775
778
|
```python
|
|
776
|
-
# Store template in manager
|
|
777
|
-
manager.
|
|
779
|
+
# Store template in manager (uses template.name automatically)
|
|
780
|
+
manager.add_template(template)
|
|
778
781
|
|
|
779
782
|
# Use by name in any well
|
|
780
783
|
view = well.WellView(depth_range=[2800, 3000], template="reservoir")
|
|
@@ -821,8 +824,8 @@ template.remove_track(2)
|
|
|
821
824
|
template.add_track(track_type="continuous", logs=[{"name": "RT"}])
|
|
822
825
|
|
|
823
826
|
# Save changes
|
|
824
|
-
manager.
|
|
825
|
-
template.save("updated_template.json")
|
|
827
|
+
manager.add_template(template) # Update in manager (uses template.name)
|
|
828
|
+
template.save("updated_template.json") # Save to file
|
|
826
829
|
```
|
|
827
830
|
|
|
828
831
|
### Customization
|
|
@@ -968,8 +971,8 @@ template.add_track(track_type="depth", width=0.3, title="MD (m)")
|
|
|
968
971
|
# Add formation tops spanning all tracks
|
|
969
972
|
template.add_tops(property_name='Zone')
|
|
970
973
|
|
|
971
|
-
#
|
|
972
|
-
manager.
|
|
974
|
+
# Add to project and display
|
|
975
|
+
manager.add_template(template)
|
|
973
976
|
view = well.WellView(depth_range=[2800, 3200], template="comprehensive")
|
|
974
977
|
view.save("comprehensive_log.png", dpi=300)
|
|
975
978
|
```
|
|
@@ -1848,7 +1851,8 @@ from well_log_toolkit import WellDataManager, Well, Property, LasFile
|
|
|
1848
1851
|
- `remove_well(name)` - Remove well
|
|
1849
1852
|
- `save(directory)` - Save project
|
|
1850
1853
|
- `load(directory)` - Load project
|
|
1851
|
-
- `
|
|
1854
|
+
- `add_template(template)` - Store template (uses template.name)
|
|
1855
|
+
- `set_template(name, template)` - Store template with custom name
|
|
1852
1856
|
- `get_template(name)` - Retrieve template
|
|
1853
1857
|
- `list_templates()` - List template names
|
|
1854
1858
|
- `Crossplot(x, y, wells=None, shape="well", ...)` - Create multi-well crossplot
|
|
@@ -2015,7 +2019,7 @@ template.add_track(
|
|
|
2015
2019
|
logs=[{"name": "GR", "x_range": [0, 150], "color": "green"}],
|
|
2016
2020
|
title="Gamma Ray"
|
|
2017
2021
|
)
|
|
2018
|
-
manager.
|
|
2022
|
+
manager.add_template(template) # Stored as "custom"
|
|
2019
2023
|
view = well.WellView(template="custom")
|
|
2020
2024
|
view.save("log.png", dpi=300)
|
|
2021
2025
|
```
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "well-log-toolkit"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.139"
|
|
8
8
|
description = "Fast LAS file processing with lazy loading and filtering for well log analysis"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -384,11 +384,18 @@ class _ManagerPropertyProxy:
|
|
|
384
384
|
|
|
385
385
|
@labels.setter
|
|
386
386
|
def labels(self, value: dict):
|
|
387
|
-
"""Set labels for this property in all wells.
|
|
387
|
+
"""Set labels for this property in all wells.
|
|
388
|
+
|
|
389
|
+
Also sets property type to 'discrete' if not already set,
|
|
390
|
+
since labels are only meaningful for discrete properties.
|
|
391
|
+
"""
|
|
388
392
|
count = 0
|
|
389
393
|
for well_name, well in self._manager._wells.items():
|
|
390
394
|
try:
|
|
391
395
|
prop = well.get_property(self._property_name)
|
|
396
|
+
# Auto-set type to discrete if labels are being set
|
|
397
|
+
if prop.type != 'discrete':
|
|
398
|
+
prop.type = 'discrete'
|
|
392
399
|
prop.labels = value
|
|
393
400
|
count += 1
|
|
394
401
|
except (AttributeError, PropertyNotFoundError):
|
|
@@ -2481,37 +2488,52 @@ class WellDataManager:
|
|
|
2481
2488
|
if well.name in self._name_mapping:
|
|
2482
2489
|
del self._name_mapping[well.name]
|
|
2483
2490
|
|
|
2491
|
+
def add_template(self, template: 'Template') -> None:
|
|
2492
|
+
"""
|
|
2493
|
+
Store a template using its built-in name.
|
|
2494
|
+
|
|
2495
|
+
Parameters
|
|
2496
|
+
----------
|
|
2497
|
+
template : Template
|
|
2498
|
+
Template object (uses template.name as the key)
|
|
2499
|
+
|
|
2500
|
+
Examples
|
|
2501
|
+
--------
|
|
2502
|
+
>>> from well_log_toolkit import Template
|
|
2503
|
+
>>>
|
|
2504
|
+
>>> template = Template("reservoir")
|
|
2505
|
+
>>> template.add_track(track_type="continuous", logs=[...])
|
|
2506
|
+
>>> manager.add_template(template) # Stored as "reservoir"
|
|
2507
|
+
>>>
|
|
2508
|
+
>>> # Use in WellView
|
|
2509
|
+
>>> view = well.WellView(template="reservoir")
|
|
2510
|
+
"""
|
|
2511
|
+
from .visualization import Template
|
|
2512
|
+
|
|
2513
|
+
if not isinstance(template, Template):
|
|
2514
|
+
raise TypeError(f"template must be Template, got {type(template).__name__}")
|
|
2515
|
+
|
|
2516
|
+
self._templates[template.name] = template
|
|
2517
|
+
|
|
2484
2518
|
def set_template(self, name: str, template: Union['Template', dict]) -> None:
|
|
2485
2519
|
"""
|
|
2486
|
-
Store a
|
|
2520
|
+
Store a template with a custom name (overrides template.name).
|
|
2487
2521
|
|
|
2488
|
-
|
|
2522
|
+
Use add_template() for the simpler case where the template's
|
|
2523
|
+
built-in name should be used.
|
|
2489
2524
|
|
|
2490
2525
|
Parameters
|
|
2491
2526
|
----------
|
|
2492
2527
|
name : str
|
|
2493
|
-
Template name for reference
|
|
2528
|
+
Template name for reference (overrides template.name)
|
|
2494
2529
|
template : Union[Template, dict]
|
|
2495
2530
|
Template object or dictionary configuration
|
|
2496
2531
|
|
|
2497
2532
|
Examples
|
|
2498
2533
|
--------
|
|
2499
|
-
>>>
|
|
2500
|
-
>>>
|
|
2501
|
-
>>> # Create and store template
|
|
2534
|
+
>>> # Store with a different name than the template's built-in name
|
|
2502
2535
|
>>> template = Template("reservoir")
|
|
2503
|
-
>>>
|
|
2504
|
-
... track_type="continuous",
|
|
2505
|
-
... logs=[{"name": "GR", "x_range": [0, 150], "color": "green"}]
|
|
2506
|
-
... )
|
|
2507
|
-
>>> manager.set_template("reservoir", template)
|
|
2508
|
-
>>>
|
|
2509
|
-
>>> # Use template in WellView
|
|
2510
|
-
>>> from well_log_toolkit.visualization import WellView
|
|
2511
|
-
>>> view = manager.well_36_7_5_A.WellView(
|
|
2512
|
-
... depth_range=[2800, 3000],
|
|
2513
|
-
... template="reservoir"
|
|
2514
|
-
... )
|
|
2536
|
+
>>> manager.set_template("reservoir_v2", template)
|
|
2515
2537
|
"""
|
|
2516
2538
|
from .visualization import Template
|
|
2517
2539
|
|
|
@@ -357,12 +357,18 @@ class Property(PropertyOperationsMixin):
|
|
|
357
357
|
"""
|
|
358
358
|
Set the label mapping and mark source as modified.
|
|
359
359
|
|
|
360
|
+
Also sets property type to 'discrete' if not already set,
|
|
361
|
+
since labels are only meaningful for discrete properties.
|
|
362
|
+
|
|
360
363
|
Parameters
|
|
361
364
|
----------
|
|
362
365
|
value : Optional[dict[int, str]]
|
|
363
366
|
Mapping of numeric values to label strings
|
|
364
367
|
"""
|
|
365
368
|
if value != self._labels:
|
|
369
|
+
# Auto-set type to discrete if labels are being set
|
|
370
|
+
if value is not None and self._type != 'discrete':
|
|
371
|
+
self.type = 'discrete' # Use setter to trigger value rounding
|
|
366
372
|
self._labels = value
|
|
367
373
|
self._mark_source_modified()
|
|
368
374
|
|
|
@@ -1120,17 +1120,18 @@ class WellView:
|
|
|
1120
1120
|
)
|
|
1121
1121
|
|
|
1122
1122
|
# Collect all tops data from all tops groups
|
|
1123
|
-
|
|
1123
|
+
all_tops_list = []
|
|
1124
1124
|
for tops_group in self.tops:
|
|
1125
|
-
|
|
1126
|
-
|
|
1125
|
+
entries = tops_group.get('entries', [])
|
|
1126
|
+
for entry in entries:
|
|
1127
|
+
all_tops_list.append((entry['depth'], entry['name']))
|
|
1127
1128
|
|
|
1128
1129
|
# Find depths for specified tops
|
|
1129
1130
|
tops_depths = []
|
|
1130
1131
|
not_found = []
|
|
1131
1132
|
for top_name in tops_list:
|
|
1132
1133
|
found = False
|
|
1133
|
-
for depth, name in
|
|
1134
|
+
for depth, name in all_tops_list:
|
|
1134
1135
|
if name == top_name:
|
|
1135
1136
|
tops_depths.append(depth)
|
|
1136
1137
|
found = True
|
|
@@ -1140,7 +1141,7 @@ class WellView:
|
|
|
1140
1141
|
|
|
1141
1142
|
# Only raise error if NONE of the tops were found
|
|
1142
1143
|
if not tops_depths:
|
|
1143
|
-
available_tops = list(set(
|
|
1144
|
+
available_tops = list(set(name for _, name in all_tops_list))
|
|
1144
1145
|
raise ValueError(
|
|
1145
1146
|
f"None of the specified formation tops were found: {tops_list}. "
|
|
1146
1147
|
f"Available tops: {available_tops}"
|
|
@@ -1338,11 +1339,8 @@ class WellView:
|
|
|
1338
1339
|
if property_name is not None and tops_dict is not None:
|
|
1339
1340
|
raise ValueError("Cannot specify both 'property_name' and 'tops_dict'")
|
|
1340
1341
|
|
|
1341
|
-
# Get tops data
|
|
1342
|
-
|
|
1343
|
-
color_data = {} # depth -> color
|
|
1344
|
-
style_data = {} # depth -> line style
|
|
1345
|
-
thickness_data = {} # depth -> line thickness
|
|
1342
|
+
# Get tops data as list of entries (supports multiple tops at same depth)
|
|
1343
|
+
tops_entries = [] # List of {'depth': d, 'name': n, 'color': c, 'style': s, 'thickness': t}
|
|
1346
1344
|
|
|
1347
1345
|
if property_name is not None:
|
|
1348
1346
|
# Load from discrete property
|
|
@@ -1375,7 +1373,7 @@ class WellView:
|
|
|
1375
1373
|
if valid_values[i] != valid_values[i-1]:
|
|
1376
1374
|
boundaries.append(i)
|
|
1377
1375
|
|
|
1378
|
-
# Build tops
|
|
1376
|
+
# Build tops entries list
|
|
1379
1377
|
for idx in boundaries:
|
|
1380
1378
|
depth = float(valid_depth[idx])
|
|
1381
1379
|
value = int(valid_values[idx])
|
|
@@ -1386,42 +1384,43 @@ class WellView:
|
|
|
1386
1384
|
else:
|
|
1387
1385
|
formation_name = f"Zone {value}"
|
|
1388
1386
|
|
|
1389
|
-
|
|
1387
|
+
entry = {'depth': depth, 'name': formation_name}
|
|
1390
1388
|
|
|
1391
1389
|
# Get color if available (colors parameter overrides property colors)
|
|
1392
1390
|
if colors is not None and value in colors:
|
|
1393
|
-
|
|
1391
|
+
entry['color'] = colors[value]
|
|
1394
1392
|
elif prop.colors and value in prop.colors:
|
|
1395
|
-
|
|
1393
|
+
entry['color'] = prop.colors[value]
|
|
1396
1394
|
|
|
1397
1395
|
# Get style if available (styles parameter overrides property styles)
|
|
1398
1396
|
if styles is not None and value in styles:
|
|
1399
|
-
|
|
1397
|
+
entry['style'] = styles[value]
|
|
1400
1398
|
elif prop.styles and value in prop.styles:
|
|
1401
|
-
|
|
1399
|
+
entry['style'] = prop.styles[value]
|
|
1402
1400
|
|
|
1403
1401
|
# Get thickness if available (thicknesses parameter overrides property thicknesses)
|
|
1404
1402
|
if thicknesses is not None and value in thicknesses:
|
|
1405
|
-
|
|
1403
|
+
entry['thickness'] = thicknesses[value]
|
|
1406
1404
|
elif prop.thicknesses and value in prop.thicknesses:
|
|
1407
|
-
|
|
1405
|
+
entry['thickness'] = prop.thicknesses[value]
|
|
1406
|
+
|
|
1407
|
+
tops_entries.append(entry)
|
|
1408
1408
|
|
|
1409
1409
|
else:
|
|
1410
|
-
# Use provided dictionary
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1410
|
+
# Use provided dictionary - convert to list format
|
|
1411
|
+
for depth, name in tops_dict.items():
|
|
1412
|
+
entry = {'depth': depth, 'name': name}
|
|
1413
|
+
if colors is not None and depth in colors:
|
|
1414
|
+
entry['color'] = colors[depth]
|
|
1415
|
+
if styles is not None and depth in styles:
|
|
1416
|
+
entry['style'] = styles[depth]
|
|
1417
|
+
if thicknesses is not None and depth in thicknesses:
|
|
1418
|
+
entry['thickness'] = thicknesses[depth]
|
|
1419
|
+
tops_entries.append(entry)
|
|
1418
1420
|
|
|
1419
1421
|
# Store tops for rendering
|
|
1420
1422
|
self.tops.append({
|
|
1421
|
-
'
|
|
1422
|
-
'colors': color_data if color_data else None,
|
|
1423
|
-
'styles': style_data if style_data else None,
|
|
1424
|
-
'thicknesses': thickness_data if thickness_data else None
|
|
1423
|
+
'entries': tops_entries
|
|
1425
1424
|
})
|
|
1426
1425
|
|
|
1427
1426
|
def _get_depth_mask(self, depth: np.ndarray) -> np.ndarray:
|
|
@@ -1451,34 +1450,21 @@ class WellView:
|
|
|
1451
1450
|
|
|
1452
1451
|
# For each tops group
|
|
1453
1452
|
for tops_group in self.tops:
|
|
1454
|
-
|
|
1455
|
-
colors_data = tops_group['colors']
|
|
1456
|
-
styles_data = tops_group['styles']
|
|
1457
|
-
thicknesses_data = tops_group['thicknesses']
|
|
1453
|
+
entries = tops_group.get('entries', [])
|
|
1458
1454
|
|
|
1459
1455
|
# Draw each top
|
|
1460
|
-
for
|
|
1456
|
+
for entry in entries:
|
|
1457
|
+
depth = entry['depth']
|
|
1458
|
+
formation_name = entry['name']
|
|
1459
|
+
|
|
1461
1460
|
# Skip tops outside depth range
|
|
1462
1461
|
if depth < self.depth_range[0] or depth > self.depth_range[1]:
|
|
1463
1462
|
continue
|
|
1464
1463
|
|
|
1465
|
-
# Get color
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
color = 'black' # Default color
|
|
1470
|
-
|
|
1471
|
-
# Get line style for this top
|
|
1472
|
-
if styles_data and depth in styles_data:
|
|
1473
|
-
linestyle = styles_data[depth]
|
|
1474
|
-
else:
|
|
1475
|
-
linestyle = 'solid' # Default style
|
|
1476
|
-
|
|
1477
|
-
# Get line thickness for this top
|
|
1478
|
-
if thicknesses_data and depth in thicknesses_data:
|
|
1479
|
-
linewidth = thicknesses_data[depth]
|
|
1480
|
-
else:
|
|
1481
|
-
linewidth = 1.5 # Default thickness
|
|
1464
|
+
# Get color, style, thickness from entry (with defaults)
|
|
1465
|
+
color = entry.get('color', 'black')
|
|
1466
|
+
linestyle = entry.get('style', 'solid')
|
|
1467
|
+
linewidth = entry.get('thickness', 1.5)
|
|
1482
1468
|
|
|
1483
1469
|
# Draw line across all non-depth tracks
|
|
1484
1470
|
for ax in non_depth_axes:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: well-log-toolkit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.139
|
|
4
4
|
Summary: Fast LAS file processing with lazy loading and filtering for well log analysis
|
|
5
5
|
Author-email: Kristian dF Kollsgård <kkollsg@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -463,7 +463,10 @@ template.add_track(track_type="continuous", logs=[...], title="Resistivity")
|
|
|
463
463
|
template.add_track(track_type="discrete", logs=[...], title="Facies")
|
|
464
464
|
template.add_track(track_type="depth", width=0.3, title="Depth")
|
|
465
465
|
|
|
466
|
-
#
|
|
466
|
+
# Add to project (saves with manager.save())
|
|
467
|
+
manager.add_template(template) # Uses template name "reservoir"
|
|
468
|
+
|
|
469
|
+
# Or save standalone file
|
|
467
470
|
template.save("reservoir_template.json")
|
|
468
471
|
```
|
|
469
472
|
|
|
@@ -811,8 +814,8 @@ view.show()
|
|
|
811
814
|
|
|
812
815
|
**Option 2: Store in manager (recommended for multi-well projects)**
|
|
813
816
|
```python
|
|
814
|
-
# Store template in manager
|
|
815
|
-
manager.
|
|
817
|
+
# Store template in manager (uses template.name automatically)
|
|
818
|
+
manager.add_template(template)
|
|
816
819
|
|
|
817
820
|
# Use by name in any well
|
|
818
821
|
view = well.WellView(depth_range=[2800, 3000], template="reservoir")
|
|
@@ -859,8 +862,8 @@ template.remove_track(2)
|
|
|
859
862
|
template.add_track(track_type="continuous", logs=[{"name": "RT"}])
|
|
860
863
|
|
|
861
864
|
# Save changes
|
|
862
|
-
manager.
|
|
863
|
-
template.save("updated_template.json")
|
|
865
|
+
manager.add_template(template) # Update in manager (uses template.name)
|
|
866
|
+
template.save("updated_template.json") # Save to file
|
|
864
867
|
```
|
|
865
868
|
|
|
866
869
|
### Customization
|
|
@@ -1006,8 +1009,8 @@ template.add_track(track_type="depth", width=0.3, title="MD (m)")
|
|
|
1006
1009
|
# Add formation tops spanning all tracks
|
|
1007
1010
|
template.add_tops(property_name='Zone')
|
|
1008
1011
|
|
|
1009
|
-
#
|
|
1010
|
-
manager.
|
|
1012
|
+
# Add to project and display
|
|
1013
|
+
manager.add_template(template)
|
|
1011
1014
|
view = well.WellView(depth_range=[2800, 3200], template="comprehensive")
|
|
1012
1015
|
view.save("comprehensive_log.png", dpi=300)
|
|
1013
1016
|
```
|
|
@@ -1886,7 +1889,8 @@ from well_log_toolkit import WellDataManager, Well, Property, LasFile
|
|
|
1886
1889
|
- `remove_well(name)` - Remove well
|
|
1887
1890
|
- `save(directory)` - Save project
|
|
1888
1891
|
- `load(directory)` - Load project
|
|
1889
|
-
- `
|
|
1892
|
+
- `add_template(template)` - Store template (uses template.name)
|
|
1893
|
+
- `set_template(name, template)` - Store template with custom name
|
|
1890
1894
|
- `get_template(name)` - Retrieve template
|
|
1891
1895
|
- `list_templates()` - List template names
|
|
1892
1896
|
- `Crossplot(x, y, wells=None, shape="well", ...)` - Create multi-well crossplot
|
|
@@ -2053,7 +2057,7 @@ template.add_track(
|
|
|
2053
2057
|
logs=[{"name": "GR", "x_range": [0, 150], "color": "green"}],
|
|
2054
2058
|
title="Gamma Ray"
|
|
2055
2059
|
)
|
|
2056
|
-
manager.
|
|
2060
|
+
manager.add_template(template) # Stored as "custom"
|
|
2057
2061
|
view = well.WellView(template="custom")
|
|
2058
2062
|
view.save("log.png", dpi=300)
|
|
2059
2063
|
```
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit.egg-info/requires.txt
RENAMED
|
File without changes
|
{well_log_toolkit-0.1.137 → well_log_toolkit-0.1.139}/well_log_toolkit.egg-info/top_level.txt
RENAMED
|
File without changes
|