lasmnemonicsid 0.0.2__py3-none-any.whl → 0.0.3rc0__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.
LASMnemonicsID/LAS/LAS.py CHANGED
@@ -20,11 +20,7 @@ from os.path import join
20
20
  from sys import stdout
21
21
  from pathlib import Path
22
22
 
23
-
24
-
25
-
26
-
27
- # Function that create the mnemonic dictionary
23
+ # Function that creates the mnemonic dictionary
28
24
  def create_mnemonic_dict(
29
25
  gamma_names,
30
26
  sp_names,
@@ -39,9 +35,8 @@ def create_mnemonic_dict(
39
35
  pe_names,
40
36
  ):
41
37
  """
42
- Function that create the mnemonic dictionary with the mnemonics per log type in the utils module
38
+ Function that creates the mnemonic dictionary with the mnemonics per log type.
43
39
  """
44
-
45
40
  mnemonic_dict = {
46
41
  "gamma": gamma_names,
47
42
  "sp": sp_names,
@@ -57,63 +52,82 @@ def create_mnemonic_dict(
57
52
  }
58
53
  return mnemonic_dict
59
54
 
60
-
61
-
62
- def parseLAS(directory_path, verbose=True):
55
+ def parseLAS(input_path, verbose=True, preferred_names=None):
63
56
  """
64
- Parse all LAS files in directory (recursive) into dict of DataFrames or single DataFrame.
57
+ Parse LAS file or all in directory DataFrame or {filename: df}.
65
58
 
66
59
  Args:
67
- directory_path (str/Path): Directory containing LAS files
68
- verbose (bool): Print processing info
60
+ input_path (str/Path): LAS file or directory
61
+ verbose (bool): Print info
62
+ preferred_names (dict, optional): Mapping of curve types to preferred column names and preferred original columns.
63
+ Example: {"deepres": "RT", "deepres_preferred_original": "AT90", "gamma": "GR"}
64
+ If not provided, defaults to standard petrophysical names.
69
65
 
70
66
  Returns:
71
- dict or DataFrame: {folder: {well: df}} or single df if one file found
67
+ DataFrame (single) or dict {filename: df} (multiple/dir)
72
68
  """
73
- directory_path = Path(directory_path)
74
- well_logs = {}
69
+ input_path = Path(input_path)
75
70
 
76
- # Find all LAS files recursively
77
- las_files = list(directory_path.rglob("*.las"))
71
+ # Define default standard names
72
+ std_names = {
73
+ "gamma": "GR",
74
+ "sp": "SP",
75
+ "caliper": "CALI",
76
+ "deepres": "RT",
77
+ "rxo": "RXO",
78
+ "density": "RHOB",
79
+ "density_correction": "DRHO",
80
+ "neutron": "NPHI",
81
+ "dtc": "DT",
82
+ "dts": "DTS",
83
+ "pe": "PEF"
84
+ }
85
+
86
+ # Update with user preferences if provided
87
+ if preferred_names:
88
+ std_names.update(preferred_names)
89
+
90
+ # Case 1: Single File
91
+ if input_path.is_file() and input_path.suffix.lower() == '.las':
92
+ df = _read_single_las(input_path, verbose, std_names)
93
+ return df if df is not None else None
78
94
 
95
+ # Case 2: Directory (Recursive)
96
+ las_files = list(input_path.rglob("*.las"))
79
97
  if not las_files:
80
98
  if verbose:
81
- print("No LAS files found.")
99
+ print(f"No LAS files found in {input_path}")
82
100
  return {}
83
101
 
84
- if len(las_files) == 1:
85
- # Return single DataFrame if only one file
86
- return _read_single_las(las_files[0], verbose)
87
-
88
- # Multiple files: group by parent folder
102
+ las_dict = {}
89
103
  for las_file in las_files:
90
- folder_name = las_file.parent.name
91
- if folder_name not in well_logs:
92
- well_logs[folder_name] = {}
93
-
94
- df = _read_single_las(las_file, verbose)
104
+ df = _read_single_las(las_file, verbose, std_names)
95
105
  if df is not None:
96
- well_name = _get_well_name(las_file)
97
- well_logs[folder_name][well_name] = df
106
+ filename = las_file.name
107
+ las_dict[filename] = df
98
108
 
99
- return well_logs
100
-
109
+ # Return single DF if only 1 file found, else dict
110
+ if len(las_dict) == 1:
111
+ return next(iter(las_dict.values()))
112
+
113
+ return las_dict
101
114
 
102
- def _read_single_las(las_file_path, verbose):
103
- """Read single LAS file to DataFrame"""
115
+ def _read_single_las(las_file_path, verbose, std_names):
116
+ """Read single LAS file to DataFrame and standardize ALL curves."""
104
117
  try:
105
118
  las_data = lasio.read(las_file_path)
106
119
  df = las_data.df()
120
+
107
121
  if df is None or df.empty:
108
122
  if verbose:
109
123
  print(f"✗ Empty DataFrame: {las_file_path.name}")
110
124
  return None
111
125
 
126
+ # Ensure index is depth (float)
112
127
  df.index = df.index.astype(float)
113
- # df.dropna(inplace=True)
114
128
 
115
- # Standardize GR curve
116
- _standardize_gr_curve(las_data, df)
129
+ # Standardize ALL curves (GR, RHOB, NPHI, etc.)
130
+ _standardize_all_curves(las_data, df, std_names)
117
131
 
118
132
  if verbose:
119
133
  print(f"✓ {las_file_path.name}")
@@ -127,7 +141,6 @@ def _read_single_las(las_file_path, verbose):
127
141
  print(f"✗ Error in {las_file_path.name}: {type(e).__name__}: {e}")
128
142
  return None
129
143
 
130
-
131
144
  def _get_well_name(las_file_path):
132
145
  """Extract well name from LAS file"""
133
146
  try:
@@ -136,13 +149,46 @@ def _get_well_name(las_file_path):
136
149
  except:
137
150
  return las_file_path.stem
138
151
 
152
+ def _standardize_all_curves(las_data, df, std_names):
153
+ """
154
+ Rename ALL curves in the DataFrame to standard abbreviations
155
+ based on the mnemonic dictionary.
156
+ """
157
+ # 1. Get the dictionary of aliases
158
+ mnem_dict = create_mnemonic_dict(
159
+ gamma_names, sp_names, caliper_names, deepres_names, rxo_names,
160
+ density_names, density_correction_names, neutron_names,
161
+ dtc_names, dts_names, pe_names
162
+ )
163
+
164
+ # 2. Track which columns we've already renamed to avoid duplicates
165
+ renamed = set()
139
166
 
140
- def _standardize_gr_curve(las_data, df):
141
- """Rename gamma ray curve to GR"""
142
- global gamma_names # Assuming gamma_names defined elsewhere
143
- for curve in las_data.curves:
144
- if curve.mnemonic.lower() in gamma_names:
145
- df.rename(columns={curve.mnemonic: "GR"}, inplace=True)
146
- break
147
-
167
+ # 3. For each curve type, find all aliases in the file
168
+ for curve_type, aliases in mnem_dict.items():
169
+ # Find all matching columns in df
170
+ matching = [col for col in df.columns if col.lower() in [a.lower() for a in aliases]]
171
+
172
+ if not matching:
173
+ continue
174
+
175
+ # Use standard name if provided, otherwise use curve_type.upper()
176
+ target_name = std_names.get(curve_type, curve_type.upper())
177
+
178
+ # If a preferred original column is specified, use it
179
+ preferred_original = std_names.get(f"{curve_type}_preferred_original")
180
+
181
+ if preferred_original and preferred_original in matching:
182
+ # Rename preferred original to target_name
183
+ df.rename(columns={preferred_original: target_name}, inplace=True)
184
+ renamed.add(target_name)
185
+ else:
186
+ # Otherwise, pick the first matching alias
187
+ df.rename(columns={matching[0]: target_name}, inplace=True)
188
+ renamed.add(target_name)
189
+
190
+ # Remove all other matching columns
191
+ for col in matching:
192
+ if col != target_name and col in df.columns:
193
+ df.drop(columns=[col], inplace=True)
148
194
 
@@ -1,12 +1,13 @@
1
1
  from .LAS import (
2
2
  parseLAS,
3
3
  create_mnemonic_dict,
4
- _read_single_las,
5
4
  _get_well_name,
6
- _standardize_gr_curve
5
+ _read_single_las # Keep helpers if needed
7
6
  )
8
7
 
9
8
  __all__ = [
10
- 'parseLAS',
11
- 'create_mnemonic_dict'
9
+ "parseLAS",
10
+ "create_mnemonic_dict",
11
+ "_get_well_name",
12
+ "_read_single_las"
12
13
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lasmnemonicsid
3
- Version: 0.0.2
3
+ Version: 0.0.3rc0
4
4
  Summary: Well log mnemonic identification using lasio and dlisio to load LAS/DLIS files into DataFrames
5
5
  Author-email: Nobleza Energy <info@nobleza-energy.com>
6
6
  License: MIT
@@ -36,7 +36,6 @@ Requires-Dist: flake8>=6.0.0; extra == "dev"
36
36
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
37
37
  Dynamic: license-file
38
38
 
39
-
40
39
  <p align="center">
41
40
  <img src="https://raw.githubusercontent.com/Nobleza-Energy/LASMnemonicsID/main/logo.png" alt="LASMnemonicsID Logo" width="200"/>
42
41
  </p>
@@ -61,10 +60,9 @@ Dynamic: license-file
61
60
  pip install lasmnemonicsid
62
61
  ```
63
62
 
64
-
65
-
66
63
  ## 🚀 QuickStart
67
- ```
64
+
65
+ ```python
68
66
  from LASMnemonicsID.LAS import parseLAS
69
67
 
70
68
  # Load LAS file
@@ -72,12 +70,41 @@ df = parseLAS("your_well.las")
72
70
  print(df.head())
73
71
  ```
74
72
 
75
- ## 🧪 Test with your Data
76
- ```
73
+ ## 🧪 Test with your Data: Multiple files will load into a dictionary
74
+
75
+ ```python
77
76
  from LASMnemonicsID.LAS import parseLAS
78
77
 
79
- # Load and inspect
80
- df = parseLAS("path/to/well.las")
81
- print(f"✅ {len(df)} rows, {len(df.columns)} curves")
82
- print(df.columns.tolist())
78
+ # Load all .las within the Directory → {filename: df}
79
+ data = parseLAS("/path/to/your/data/")
80
+ print("Files:", list(data.keys()))
81
+
82
+ # Dataframes
83
+ df = parseLAS('/path/to/yourfile.las')
84
+ print(df.head())
83
85
  ```
86
+
87
+ ## 📈 Star History
88
+
89
+ [![Star History Chart](https://api.star-history.com/svg?repos=Nobleza-Energy/LASMnemonicsID&type=Date)](https://star-history.com/#Nobleza-Energy/LASMnemonicsID&Date)
90
+
91
+
92
+ ## 📄 How to Cite
93
+
94
+ If you use `LASMnemonicsID` in your research or project, please cite it as follows:
95
+
96
+ **APA**
97
+
98
+ > Nobleza Energy. (2025). LASMnemonicsID: Well log mnemonic identification using lasio and dlisio [Software]. GitHub. https://github.com/Nobleza-Energy/LASMnemonicsID
99
+
100
+ **BibTeX**
101
+
102
+ ```bibtex
103
+ @software{LASMnemonicsID,
104
+ author = {Nobleza Energy},
105
+ title = {LASMnemonicsID: Well log mnemonic identification using lasio and dlisio},
106
+ year = {2025},
107
+ publisher = {GitHub},
108
+ journal = {GitHub repository},
109
+ url = {https://github.com/Nobleza-Energy/LASMnemonicsID}
110
+ }
@@ -0,0 +1,11 @@
1
+ LASMnemonicsID/__init__.py,sha256=IjJHoiHWr1CfP3K01xW61UhnJYP_9LOOaCqJnhLFlPc,309
2
+ LASMnemonicsID/DLIS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ LASMnemonicsID/LAS/LAS.py,sha256=gxeLlARZJV3ECxIQaoqO8YeOUfnlMUBKXqRFY-JivCs,6048
4
+ LASMnemonicsID/LAS/__init__.py,sha256=dTM87nn0zNUaKp29HocOODJT_-VM1CZED9Ar_FSOr-4,232
5
+ LASMnemonicsID/utils/__init__.py,sha256=ree81DUTsdjXfO3h-q7YyNrV6mTIKSGxgWPWGGTSVU0,1388
6
+ LASMnemonicsID/utils/mnemonics.py,sha256=VU25CXmQvUo0sS3Y6kG_G7KwRE2CiuoJeC7LT6FmNzg,7283
7
+ lasmnemonicsid-0.0.3rc0.dist-info/licenses/LICENSE,sha256=6r9JOUiNw1exfcc0jlOi50fDStidfqyQ2PAYQh4lzEQ,1071
8
+ lasmnemonicsid-0.0.3rc0.dist-info/METADATA,sha256=AXUCpIS5uLGwI6yGlBIctpyI0EN-KZGo5u6cimjOi_E,3706
9
+ lasmnemonicsid-0.0.3rc0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
10
+ lasmnemonicsid-0.0.3rc0.dist-info/top_level.txt,sha256=bdt6EHMrwbzFA9jA_xbTqRrOV6T4zDs3QojjEz8HSBk,15
11
+ lasmnemonicsid-0.0.3rc0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,11 +0,0 @@
1
- LASMnemonicsID/__init__.py,sha256=IjJHoiHWr1CfP3K01xW61UhnJYP_9LOOaCqJnhLFlPc,309
2
- LASMnemonicsID/DLIS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- LASMnemonicsID/LAS/LAS.py,sha256=7WRetjZG9-M39KNxpUisAkbh8mv60BWW-uTEUkwvkF8,3849
4
- LASMnemonicsID/LAS/__init__.py,sha256=4cNesZ581Cl_PN_c4DHTGfkc5HiKtnbhP81vJ6-3nPM,187
5
- LASMnemonicsID/utils/__init__.py,sha256=ree81DUTsdjXfO3h-q7YyNrV6mTIKSGxgWPWGGTSVU0,1388
6
- LASMnemonicsID/utils/mnemonics.py,sha256=VU25CXmQvUo0sS3Y6kG_G7KwRE2CiuoJeC7LT6FmNzg,7283
7
- lasmnemonicsid-0.0.2.dist-info/licenses/LICENSE,sha256=6r9JOUiNw1exfcc0jlOi50fDStidfqyQ2PAYQh4lzEQ,1071
8
- lasmnemonicsid-0.0.2.dist-info/METADATA,sha256=9XdXauxiGe80GgPo9GWFrbAjSGxoyOibBPmGPmJ-WLk,2811
9
- lasmnemonicsid-0.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
- lasmnemonicsid-0.0.2.dist-info/top_level.txt,sha256=bdt6EHMrwbzFA9jA_xbTqRrOV6T4zDs3QojjEz8HSBk,15
11
- lasmnemonicsid-0.0.2.dist-info/RECORD,,