well-log-toolkit 0.1.125__py3-none-any.whl → 0.1.127__py3-none-any.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.
@@ -1510,7 +1510,8 @@ class WellDataManager:
1510
1510
  path: Optional[Union[str, Path]] = None,
1511
1511
  sampled: bool = False,
1512
1512
  combine: Optional[str] = None,
1513
- source_name: Optional[str] = None
1513
+ source_name: Optional[str] = None,
1514
+ silent: bool = False
1514
1515
  ) -> 'WellDataManager':
1515
1516
  """
1516
1517
  Load LAS file(s), auto-create well if needed.
@@ -1538,6 +1539,9 @@ class WellDataManager:
1538
1539
  Name for combined source when combine is specified. If not specified,
1539
1540
  uses 'combined_match', 'combined_resample', or 'combined_concat'.
1540
1541
  When files span multiple wells, the well name is prepended automatically.
1542
+ silent : bool, default False
1543
+ If True, suppress debug output showing which sources were loaded.
1544
+ Useful when loading many files programmatically.
1541
1545
 
1542
1546
  Returns
1543
1547
  -------
@@ -1633,9 +1637,10 @@ class WellDataManager:
1633
1637
  )
1634
1638
 
1635
1639
  # Print debug output
1636
- print("Loaded sources:")
1637
- for well_name, src_name, file_count in loaded_sources:
1638
- print(f" - Well {well_name}: {src_name} ({file_count} file{'s' if file_count > 1 else ''} combined)")
1640
+ if not silent:
1641
+ print("Loaded sources:")
1642
+ for well_name, src_name, file_count in loaded_sources:
1643
+ print(f" - Well {well_name}: {src_name} ({file_count} file{'s' if file_count > 1 else ''} combined)")
1639
1644
 
1640
1645
  return self
1641
1646
 
@@ -1668,7 +1673,7 @@ class WellDataManager:
1668
1673
  loaded_sources.append((well_name, src_name))
1669
1674
 
1670
1675
  # Print debug output
1671
- if loaded_sources:
1676
+ if not silent and loaded_sources:
1672
1677
  print("Loaded sources:")
1673
1678
  for well_name, src_name in loaded_sources:
1674
1679
  print(f" - Well {well_name}: {src_name}")
@@ -1715,7 +1720,7 @@ class WellDataManager:
1715
1720
  new_sources = set(self._wells[well_key].sources) - existing_sources
1716
1721
 
1717
1722
  # Print debug output
1718
- if new_sources:
1723
+ if not silent and new_sources:
1719
1724
  print("Loaded sources:")
1720
1725
  for src_name in new_sources:
1721
1726
  print(f" - Well {well_name}: {src_name}")
@@ -2342,7 +2347,7 @@ class WellDataManager:
2342
2347
  las_files = list(base_path.glob("*.las"))
2343
2348
  if las_files:
2344
2349
  for las_file in las_files:
2345
- self.load_las(las_file)
2350
+ self.load_las(las_file, silent=True)
2346
2351
  return self
2347
2352
 
2348
2353
  # Load from well folders
@@ -2350,7 +2355,7 @@ class WellDataManager:
2350
2355
  # Find all LAS files in this folder
2351
2356
  las_files = sorted(well_folder.glob("*.las"))
2352
2357
  for las_file in las_files:
2353
- self.load_las(las_file)
2358
+ self.load_las(las_file, silent=True)
2354
2359
 
2355
2360
  return self
2356
2361
 
@@ -24,6 +24,7 @@ from .regression import (
24
24
  LinearRegression, LogarithmicRegression, ExponentialRegression,
25
25
  PolynomialRegression, PowerRegression
26
26
  )
27
+ from .exceptions import PropertyNotFoundError
27
28
 
28
29
  # Default color palettes
29
30
  DEFAULT_COLORS = [
@@ -3033,7 +3034,7 @@ class Crossplot:
3033
3034
  if needs_alignment(color_prop.depth, depths):
3034
3035
  color_values = np.interp(depths, color_prop.depth, color_prop.values, left=np.nan, right=np.nan)
3035
3036
  df['color_val'] = color_values
3036
- except (AttributeError, KeyError):
3037
+ except (AttributeError, KeyError, PropertyNotFoundError):
3037
3038
  warnings.warn(f"Color property '{self.color}' not found in well '{well.name}', using depth")
3038
3039
  df['color_val'] = depths
3039
3040
  elif self.color == "depth":
@@ -3048,7 +3049,7 @@ class Crossplot:
3048
3049
  if needs_alignment(size_prop.depth, depths):
3049
3050
  size_values = np.interp(depths, size_prop.depth, size_prop.values, left=np.nan, right=np.nan)
3050
3051
  df['size_val'] = size_values
3051
- except (AttributeError, KeyError):
3052
+ except (AttributeError, KeyError, PropertyNotFoundError):
3052
3053
  warnings.warn(f"Size property '{self.size}' not found in well '{well.name}'")
3053
3054
 
3054
3055
  # Add shape property if specified and not "well"
@@ -3060,12 +3061,12 @@ class Crossplot:
3060
3061
  if needs_alignment(shape_prop.depth, depths):
3061
3062
  shape_values = np.interp(depths, shape_prop.depth, shape_prop.values, left=np.nan, right=np.nan)
3062
3063
  df['shape_val'] = shape_values
3063
- except (AttributeError, KeyError):
3064
+ except (AttributeError, KeyError, PropertyNotFoundError):
3064
3065
  warnings.warn(f"Shape property '{self.shape}' not found in well '{well.name}'")
3065
3066
 
3066
3067
  all_data.append(df)
3067
3068
 
3068
- except (AttributeError, KeyError) as e:
3069
+ except (AttributeError, KeyError, PropertyNotFoundError) as e:
3069
3070
  warnings.warn(f"Could not get properties for well '{well.name}': {e}")
3070
3071
  continue
3071
3072
 
well_log_toolkit/well.py CHANGED
@@ -457,27 +457,49 @@ class Well:
457
457
  las_files = las
458
458
 
459
459
  # Load all files as separate sources
460
+ # Track sources before and after to identify what was loaded
460
461
  loaded_sources = []
462
+
461
463
  for las_file in las_files:
464
+ # Track sources before this file
465
+ sources_before = set(self.sources)
466
+
462
467
  # Recursively call load_las for each file (without merge or combine, path already prepended)
463
468
  self.load_las(las_file, path=None, sampled=sampled, resample_method=resample_method, merge=False, combine=None)
464
- # Get the source name that was just created
465
- loaded_sources.append(self.sources[-1])
469
+
470
+ # Find which source was added or modified
471
+ sources_after = set(self.sources)
472
+ new_or_modified = sources_after - sources_before
473
+
474
+ if new_or_modified:
475
+ # New source was added
476
+ loaded_sources.append(list(new_or_modified)[0])
477
+ else:
478
+ # Source was overwritten - find it by checking which source is newest
479
+ # Since we don't know which one, we'll use the last one in the list
480
+ # This handles the overwrite case
481
+ if self.sources:
482
+ loaded_sources.append(self.sources[-1])
466
483
 
467
484
  # Combine if requested
468
485
  if combine in {'match', 'resample', 'concat'}:
469
486
  # Determine combined source name
470
487
  combined_source_name = source_name or f'combined_{combine}'
471
488
 
472
- # Merge all loaded sources
473
- self.merge(
474
- method=combine,
475
- sources=loaded_sources,
476
- source_name=combined_source_name
477
- )
489
+ # Merge all loaded sources (only ones that exist)
490
+ sources_to_merge = [s for s in loaded_sources if s in self._sources]
491
+
492
+ if sources_to_merge:
493
+ self.merge(
494
+ method=combine,
495
+ sources=sources_to_merge,
496
+ source_name=combined_source_name
497
+ )
478
498
 
479
- # Remove original sources
480
- self.remove_source(loaded_sources)
499
+ # Remove original sources (only ones that exist)
500
+ sources_to_remove = [s for s in sources_to_merge if s in self._sources]
501
+ if sources_to_remove:
502
+ self.remove_source(sources_to_remove)
481
503
 
482
504
  return self
483
505
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: well-log-toolkit
3
- Version: 0.1.125
3
+ Version: 0.1.127
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
@@ -1,15 +1,15 @@
1
1
  well_log_toolkit/__init__.py,sha256=ilJAIIhh68pYfD9I3V53juTEJpoMN8oHpcpEFNpuXAQ,3793
2
2
  well_log_toolkit/exceptions.py,sha256=X_fzC7d4yaBFO9Vx74dEIB6xmI9Agi6_bTU3MPxn6ko,985
3
3
  well_log_toolkit/las_file.py,sha256=Tj0mRfX1aX2s6uug7BBlY1m_mu3G50EGxHGzD0eEedE,53876
4
- well_log_toolkit/manager.py,sha256=7v2zzdkUc_WFCdjZwn4DFHW5pkowtC85LS3o4lvZ9bI,109002
4
+ well_log_toolkit/manager.py,sha256=STXkr5qxvxDJ9nqgAKTnZjIZ8RYgFUYdGKiCrYi5mlY,109307
5
5
  well_log_toolkit/operations.py,sha256=z8j8fGBOwoJGUQFy-Vawjq9nm3OD_dUt0oaNh8yuG7o,18515
6
6
  well_log_toolkit/property.py,sha256=WOzoNQcmHCQ8moIKsnSyLgVC8s4LBu2x5IBXtFzmMe8,76236
7
7
  well_log_toolkit/regression.py,sha256=7D3oI-1XVlFb-mOoHTxTTtUHERFyvQSBAzJzAGVoZnk,25192
8
8
  well_log_toolkit/statistics.py,sha256=_huPMbv2H3o9ezunjEM94mJknX5wPK8V4nDv2lIZZRw,16814
9
9
  well_log_toolkit/utils.py,sha256=O2KPq4htIoUlL74V2zKftdqqTjRfezU9M-568zPLme0,6866
10
- well_log_toolkit/visualization.py,sha256=xb870FG5FghU2gEkqdn1b2NbWNu07oDmFDN1Cx1HIi0,157280
11
- well_log_toolkit/well.py,sha256=kIN3Zr0sI3Zt3DeHbxDXADbQfWnVxXCQrHZ4UEMyeqI,103343
12
- well_log_toolkit-0.1.125.dist-info/METADATA,sha256=I3JrySR3JycP7qOsp4gCCOKme-hcasI-VkhbaArGsRg,59810
13
- well_log_toolkit-0.1.125.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
- well_log_toolkit-0.1.125.dist-info/top_level.txt,sha256=BMOo7OKLcZEnjo0wOLMclwzwTbYKYh31I8RGDOGSBdE,17
15
- well_log_toolkit-0.1.125.dist-info/RECORD,,
10
+ well_log_toolkit/visualization.py,sha256=tNaS1BPr1kLmr73BKqCBOSMptDdsxVofDic6vJ1iyr4,157418
11
+ well_log_toolkit/well.py,sha256=7RzbC7zud5M53zZ8FmuQP0GPhUP5Y6RiFjTuf4_oMWE,104419
12
+ well_log_toolkit-0.1.127.dist-info/METADATA,sha256=6WtUXbcWy0jWgfCF2Fv06MoBHIvEJREjksDth_Q-PL8,59810
13
+ well_log_toolkit-0.1.127.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ well_log_toolkit-0.1.127.dist-info/top_level.txt,sha256=BMOo7OKLcZEnjo0wOLMclwzwTbYKYh31I8RGDOGSBdE,17
15
+ well_log_toolkit-0.1.127.dist-info/RECORD,,