UCS2014 commited on
Commit
0003c76
·
verified ·
1 Parent(s): a68e4d3

Rename app.py to app_toc.py

Browse files
Files changed (1) hide show
  1. app.py → app_toc.py +41 -51
app.py → app_toc.py RENAMED
@@ -20,24 +20,16 @@ from sklearn.metrics import mean_squared_error # MAE removed
20
  # =========================
21
  # Constants / Defaults
22
  # =========================
23
- APP_NAME = "ST_GeoMech_UCS"
24
- TAGLINE = "Real-Time Unconfined Compressive Strength Tracking While Drilling"
25
-
26
- # Default features standardized to match Ts/Tc apps.
27
- # (Older headers are still accepted via alias map below.)
28
- FEATURES = [
29
- "WOB (klbf)",
30
- "Torque (kft.lbf)",
31
- "SPP (psi)",
32
- "RPM (1/min)",
33
- "ROP (ft/h)",
34
- "Flow Rate (gpm)",
35
- ]
36
- TARGET = "UCS"
37
- PRED_COL = "UCS_Pred"
38
 
39
  MODELS_DIR = Path("models")
40
- DEFAULT_MODEL = MODELS_DIR / "ucs_rf.joblib"
 
41
  MODEL_FALLBACKS = [MODELS_DIR / "model.joblib", MODELS_DIR / "model.pkl"]
42
  COLORS = {"pred": "#1f77b4", "actual": "#f2b702", "ref": "#5a5a5a"}
43
 
@@ -165,42 +157,40 @@ def read_book_bytes(b: bytes):
165
 
166
  # ---- Canonical feature aliasing (accept legacy headers) ----
167
  def _build_alias_map(canonical_features: list[str], target_name: str) -> dict:
168
- """
169
- Map common header variants -> canonical names (from meta FEATURES).
170
- """
171
- def pick(expected_list, variants):
172
  for v in variants:
173
- if v in expected_list:
174
- return v
175
  return variants[0]
176
 
177
- can_WOB = pick(canonical_features, ["WOB (klbf)", "WOB, klbf", "WOB(klbf)", "WOB( klbf)"])
178
- can_TORQUE = pick(canonical_features, ["Torque (kft.lbf)", "Torque(kft.lbf)", "T (kft.lbf)", "TORQUE(kft.lbf)"])
179
- can_SPP = pick(canonical_features, ["SPP (psi)", "SPP(psi)"])
180
- can_RPM = pick(canonical_features, ["RPM (1/min)", "RPM(1/min)"])
181
- can_ROP = pick(canonical_features, ["ROP (ft/h)", "ROP(ft/h)"])
182
- can_FR = pick(canonical_features, ["Flow Rate (gpm)", "Q, gpm", "Flow Rate, gpm", "Flow Rate,gpm", "Flow Rate , gpm"])
183
- can_DEPTH = "Depth (ft)"
 
 
184
 
185
  alias = {
186
- # Features
187
- "WOB (klbf)": can_WOB, "WOB, klbf": can_WOB, "WOB(klbf)": can_WOB, "WOB( klbf)": can_WOB,
188
- "Torque (kft.lbf)": can_TORQUE, "Torque(kft.lbf)": can_TORQUE, "T (kft.lbf)": can_TORQUE, "TORQUE(kft.lbf)": can_TORQUE,
189
- "SPP (psi)": can_SPP, "SPP(psi)": can_SPP,
190
- "RPM (1/min)": can_RPM, "RPM(1/min)": can_RPM,
191
- "ROP (ft/h)": can_ROP, "ROP(ft/h)": can_ROP,
192
- "Flow Rate (gpm)": can_FR, "Q, gpm": can_FR, "Flow Rate, gpm": can_FR, "Flow Rate,gpm": can_FR, "Flow Rate , gpm": can_FR,
193
-
194
- # Depth (plot only)
195
- "Depth (ft)": can_DEPTH, "Depth, ft": can_DEPTH, "Depth(ft)": can_DEPTH, "DEPTH, ft": can_DEPTH,
196
-
197
- # Target aliases
198
- "UCS": target_name,
199
- "UCS (psi)": target_name,
200
- "UCS_Actual": target_name,
201
  }
202
  return alias
203
 
 
204
  def _normalize_columns(df: pd.DataFrame, canonical_features: list[str], target_name: str) -> pd.DataFrame:
205
  out = df.copy()
206
  out.columns = [str(c).strip().replace(" ,", ",").replace(", ", ", ").replace(" ", " ") for c in out.columns]
@@ -368,7 +358,7 @@ def build_export_workbook(selected: list[str] | None = None) -> tuple[bytes|None
368
  df.to_excel(writer, sheet_name=_excel_safe_name(name), index=False)
369
  bio.seek(0)
370
 
371
- fname = f"UCS_Export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
372
  return bio.getvalue(), fname, order
373
 
374
  def render_export_button(phase_key: str) -> None:
@@ -405,7 +395,7 @@ def render_export_button(phase_key: str) -> None:
405
  st.download_button(
406
  "⬇️ Export Excel",
407
  data=(data or b""),
408
- file_name=(fname or "UCS_Export.xlsx"),
409
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
410
  disabled=(data is None),
411
  key=f"download_{phase_key}",
@@ -437,8 +427,8 @@ def cross_plot_static(actual, pred):
437
  fmt = FuncFormatter(lambda x, _: f"{x:,.0f}")
438
  ax.xaxis.set_major_formatter(fmt); ax.yaxis.set_major_formatter(fmt)
439
 
440
- ax.set_xlabel("Actual UCS (psi)", fontweight="bold", fontsize=10, color="black")
441
- ax.set_ylabel("Predicted UCS (psi)", fontweight="bold", fontsize=10, color="black")
442
  ax.tick_params(labelsize=6, colors="black")
443
 
444
  ax.grid(True, linestyle=":", alpha=0.3)
@@ -492,9 +482,9 @@ def track_plot(df, include_actual=True):
492
  legend=dict(x=0.98, y=0.05, xanchor="right", yanchor="bottom",
493
  bgcolor="rgba(255,255,255,0.75)", bordercolor="#ccc", borderwidth=1),
494
  legend_title_text=""
495
- )
496
  fig.update_xaxes(
497
- title_text="UCS (psi)",
498
  title_font=dict(size=20, family=BOLD_FONT, color="#000"),
499
  tickfont=dict(size=12, family=BOLD_FONT, color="#000"),
500
  side="top", range=[xmin, xmax],
@@ -588,7 +578,7 @@ except Exception as e:
588
 
589
  # Prefer UCS-specific meta
590
  meta = {}
591
- meta_candidates = [MODELS_DIR / "ucs_meta.json", MODELS_DIR / "meta.json"]
592
  meta_path = next((p for p in meta_candidates if p.exists()), None)
593
  if meta_path:
594
  try:
 
20
  # =========================
21
  # Constants / Defaults
22
  # =========================
23
+ APP_NAME = "ST_GeoMech_TOC"
24
+ TAGLINE = "Real-Time Total Organic Carbon Estimation While Drilling"
25
+
26
+ FEATURES = ["AHT90", "DT", "GR", "K", "RHOB", "TNPH", "Th", "Ur"]
27
+ TARGET = "TOC"
28
+ PRED_COL = "TOC_Pred"
 
 
 
 
 
 
 
 
 
29
 
30
  MODELS_DIR = Path("models")
31
+ DEFAULT_MODEL = MODELS_DIR / "toc_rf.joblib" # <— point to your TOC model
32
+
33
  MODEL_FALLBACKS = [MODELS_DIR / "model.joblib", MODELS_DIR / "model.pkl"]
34
  COLORS = {"pred": "#1f77b4", "actual": "#f2b702", "ref": "#5a5a5a"}
35
 
 
157
 
158
  # ---- Canonical feature aliasing (accept legacy headers) ----
159
  def _build_alias_map(canonical_features: list[str], target_name: str) -> dict:
160
+ def pick(expected, variants):
 
 
 
161
  for v in variants:
162
+ if v in expected: return v
 
163
  return variants[0]
164
 
165
+ # TOC logs/features
166
+ can_GR = pick(canonical_features, ["GR", "Gamma Ray", "GR (API)"])
167
+ can_RHOB = pick(canonical_features, ["RHOB", "Bulk Density", "RHOB (g/cc)"])
168
+ can_DT = pick(canonical_features, ["DT", "AC", "DT (us/ft)"])
169
+ can_TNPH = pick(canonical_features, ["TNPH", "NPHI", "TNPH (%)"])
170
+ can_K = pick(canonical_features, ["K", "Potassium", "K (%)"])
171
+ can_Th = pick(canonical_features, ["Th", "Thorium", "Th (ppm)"])
172
+ can_Ur = pick(canonical_features, ["Ur", "U", "U (ppm)"])
173
+ can_AHT = pick(canonical_features, ["AHT90", "AHT_90", "AHT-90"])
174
 
175
  alias = {
176
+ "GR": can_GR, "Gamma Ray": can_GR, "GR (API)": can_GR,
177
+ "RHOB": can_RHOB, "Bulk Density": can_RHOB, "RHOB (g/cc)": can_RHOB,
178
+ "DT": can_DT, "AC": can_DT, "DT (us/ft)": can_DT,
179
+ "TNPH": can_TNPH, "NPHI": can_TNPH, "TNPH (%)": can_TNPH,
180
+ "K": can_K, "Potassium": can_K, "K (%)": can_K,
181
+ "Th": can_Th, "Thorium": can_Th, "Th (ppm)": can_Th,
182
+ "Ur": can_Ur, "U": can_Ur, "U (ppm)": can_Ur,
183
+ "AHT90": can_AHT, "AHT_90": can_AHT, "AHT-90": can_AHT,
184
+
185
+ # Optional depth for tracks
186
+ "Depth (ft)": "Depth (ft)", "DEPTH": "Depth (ft)", "MD (ft)": "Depth (ft)",
187
+
188
+ # Targets
189
+ "TOC": target_name, "TOC (%)": target_name, "Total Organic Carbon": target_name,
 
190
  }
191
  return alias
192
 
193
+
194
  def _normalize_columns(df: pd.DataFrame, canonical_features: list[str], target_name: str) -> pd.DataFrame:
195
  out = df.copy()
196
  out.columns = [str(c).strip().replace(" ,", ",").replace(", ", ", ").replace(" ", " ") for c in out.columns]
 
358
  df.to_excel(writer, sheet_name=_excel_safe_name(name), index=False)
359
  bio.seek(0)
360
 
361
+ fname = f"TOC_Export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
362
  return bio.getvalue(), fname, order
363
 
364
  def render_export_button(phase_key: str) -> None:
 
395
  st.download_button(
396
  "⬇️ Export Excel",
397
  data=(data or b""),
398
+ file_name=(fname or "TOC_Export.xlsx"),
399
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
400
  disabled=(data is None),
401
  key=f"download_{phase_key}",
 
427
  fmt = FuncFormatter(lambda x, _: f"{x:,.0f}")
428
  ax.xaxis.set_major_formatter(fmt); ax.yaxis.set_major_formatter(fmt)
429
 
430
+ ax.set_xlabel("Actual TOC (%)", fontweight="bold", fontsize=10, color="black")
431
+ ax.set_ylabel("Predicted TOC (%)", fontweight="bold", fontsize=10, color="black")
432
  ax.tick_params(labelsize=6, colors="black")
433
 
434
  ax.grid(True, linestyle=":", alpha=0.3)
 
482
  legend=dict(x=0.98, y=0.05, xanchor="right", yanchor="bottom",
483
  bgcolor="rgba(255,255,255,0.75)", bordercolor="#ccc", borderwidth=1),
484
  legend_title_text=""
485
+ )
486
  fig.update_xaxes(
487
+ title_text="TOC (%)",
488
  title_font=dict(size=20, family=BOLD_FONT, color="#000"),
489
  tickfont=dict(size=12, family=BOLD_FONT, color="#000"),
490
  side="top", range=[xmin, xmax],
 
578
 
579
  # Prefer UCS-specific meta
580
  meta = {}
581
+ meta_candidates = [MODELS_DIR / "toc_meta.json", MODELS_DIR / "meta.json"]
582
  meta_path = next((p for p in meta_candidates if p.exists()), None)
583
  if meta_path:
584
  try: