UCS2014 commited on
Commit
3c2dd69
·
verified ·
1 Parent(s): db00578

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -33
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # app.py — ST_Sonic_Ts (Shear Slowness Ts)
2
 
3
  import io, json, os, base64, math
4
  from pathlib import Path
@@ -18,12 +18,12 @@ import plotly.graph_objects as go
18
  from sklearn.metrics import mean_squared_error, mean_absolute_error
19
 
20
  # =========================
21
- # Constants (Ts variant)
22
  # =========================
23
- APP_NAME = "ST_Log_Sonic (Ts)"
24
- TAGLINE = "Real-Time Shear Slowness (Ts) Prediction"
25
 
26
- # Defaults (overridden by ts_meta.json if present)
27
  FEATURES = [
28
  "WOB (klbf)",
29
  "Torque (kft.lbf)",
@@ -32,11 +32,11 @@ FEATURES = [
32
  "ROP (ft/h)",
33
  "Flow Rate (gpm)",
34
  ]
35
- TARGET = "Ts (us/ft_Actual)"
36
- PRED_COL = "Ts_Pred"
37
 
38
  MODELS_DIR = Path("models")
39
- DEFAULT_MODEL = MODELS_DIR / "ts_model.joblib"
40
  MODEL_FALLBACKS = [MODELS_DIR / "model.joblib", MODELS_DIR / "model.pkl"]
41
  COLORS = {"pred": "#1f77b4", "actual": "#f2b702", "ref": "#5a5a5a"}
42
 
@@ -63,8 +63,8 @@ st.markdown("""
63
  .st-message-box.st-success { background-color: #d4edda; color: #155724; border-color: #c3e6cb; }
64
  .st-message-box.st-warning { background-color: #fff3cd; color: #856404; border-color: #ffeeba; }
65
  .st-message-box.st-error { background-color: #f8d7da; color: #721c24; border-color: #f5c6cb; }
66
- .main .block-container { overflow: unset !important; }
67
- div[data-testid="stVerticalBlock"] { overflow: unset !important; }
68
  div[data-testid="stExpander"] > details > summary {
69
  position: sticky; top: 0; z-index: 10; background: #fff; border-bottom: 1px solid #eee;
70
  }
@@ -152,7 +152,7 @@ def read_book_bytes(b: bytes):
152
  def _build_alias_map(canonical_features: list[str], target_name: str) -> dict:
153
  """
154
  Map common header variants -> the *canonical* names in canonical_features.
155
- Whatever appears in canonical_features (from ts_meta.json) wins.
156
  """
157
  def pick(expected_list, variants):
158
  for v in variants:
@@ -181,13 +181,13 @@ def _build_alias_map(canonical_features: list[str], target_name: str) -> dict:
181
  # Depth (plot only)
182
  "Depth (ft)": can_DEPTH, "Depth, ft": can_DEPTH, "Depth(ft)": can_DEPTH, "DEPTH, ft": can_DEPTH,
183
 
184
- # Target family
185
- "Ts (us/ft_Actual)": target_name,
186
- "Ts,us/ft_Actual": target_name,
187
- "Ts, us/ft_Actual": target_name,
188
- "Ts": target_name,
189
- "TS_Actual": target_name,
190
- "Ts (us/ft)_Actual": target_name,
191
  }
192
  return alias
193
 
@@ -365,7 +365,7 @@ def build_export_workbook(selected: list[str], ndigits: int = 3, do_autofit: boo
365
  if do_autofit:
366
  _excel_autofit(writer, sheet, df)
367
  bio.seek(0)
368
- fname = f"TS_Export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
369
  return bio.getvalue(), fname, order
370
 
371
  # --------- SIMPLE export UI ----------
@@ -390,7 +390,7 @@ def render_export_button(phase_key: str) -> None:
390
  st.download_button(
391
  label="⬇️ Export Excel",
392
  data=b"",
393
- file_name="TS_Export.xlsx",
394
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
395
  disabled=True,
396
  key=f"download_{phase_key}",
@@ -403,7 +403,7 @@ def render_export_button(phase_key: str) -> None:
403
  st.download_button(
404
  "⬇️ Export Excel",
405
  data=(data or b""),
406
- file_name=(fname or "TS_Export.xlsx"),
407
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
408
  disabled=(data is None),
409
  key=f"download_{phase_key}",
@@ -412,7 +412,7 @@ def render_export_button(phase_key: str) -> None:
412
  # =========================
413
  # Cross plot (Matplotlib)
414
  # =========================
415
- def cross_plot_static(actual, pred, xlabel="Actual Ts (µs/ft)", ylabel="Predicted Ts (µs/ft)"):
416
  a = pd.Series(actual, dtype=float)
417
  p = pd.Series(pred, dtype=float)
418
 
@@ -494,7 +494,7 @@ def track_plot(df, include_actual=True):
494
  legend_title_text=""
495
  )
496
  fig.update_xaxes(
497
- title_text="Ts (μs/ft)",
498
  title_font=dict(size=20, family=BOLD_FONT, color="#000"),
499
  tickfont=dict(size=15, family=BOLD_FONT, color="#000"),
500
  side="top", range=[xmin, xmax],
@@ -587,7 +587,7 @@ def ensure_model() -> Path|None:
587
 
588
  mpath = ensure_model()
589
  if not mpath:
590
- st.error("Model not found. Upload models/ts_model.joblib (or set MODEL_URL).")
591
  st.stop()
592
  try:
593
  model = load_model(str(mpath))
@@ -595,9 +595,9 @@ except Exception as e:
595
  st.error(f"Failed to load model: {e}")
596
  st.stop()
597
 
598
- # Load meta (prefer Ts-specific)
599
  meta = {}
600
- meta_candidates = [MODELS_DIR / "ts_meta.json", MODELS_DIR / "meta.json", MODELS_DIR / "ym_meta.json"]
601
  meta_path = next((p for p in meta_candidates if p.exists()), None)
602
  if meta_path:
603
  try:
@@ -665,12 +665,12 @@ def sticky_header(title, message):
665
  # =========================
666
  if st.session_state.app_step == "intro":
667
  st.header("Welcome!")
668
- st.markdown("This software is developed by *Smart Thinking AI-Solutions Team* to estimate **Shear Slowness (Ts)** from drilling data.")
669
  st.subheader("How It Works")
670
  st.markdown(
671
  "1) **Upload your data to build the case and preview the model performance.** \n"
672
  "2) Click **Run Model** to compute metrics and plots. \n"
673
- "3) **Proceed to Validation** (with actual Ts) or **Proceed to Prediction** (no Ts)."
674
  )
675
  if st.button("Start Showcase", type="primary"):
676
  st.session_state.app_step = "dev"; st.rerun()
@@ -767,7 +767,7 @@ if st.session_state.app_step == "dev":
767
  render_export_button(phase_key="dev")
768
 
769
  # =========================
770
- # VALIDATION (with actual Ts)
771
  # =========================
772
  if st.session_state.app_step == "validate":
773
  st.sidebar.header("Validate the Model")
@@ -783,7 +783,7 @@ if st.session_state.app_step == "validate":
783
  if st.sidebar.button("⬅ Back to Case Building", use_container_width=True): st.session_state.app_step="dev"; st.rerun()
784
  if st.sidebar.button("Proceed to Prediction ▶", use_container_width=True): st.session_state.app_step="predict"; st.rerun()
785
 
786
- sticky_header("Validate the Model", "Upload a dataset with the same **features** and **Ts** to evaluate performance.")
787
 
788
  if go_btn and up is not None:
789
  book = read_book_bytes(up.getvalue())
@@ -843,10 +843,10 @@ if st.session_state.app_step == "validate":
843
  df_centered_rounded(st.session_state.results["oor_tbl"])
844
 
845
  # =========================
846
- # PREDICTION (no actual Ts)
847
  # =========================
848
  if st.session_state.app_step == "predict":
849
- st.sidebar.header("Prediction (No Actual Ts)")
850
  up = st.sidebar.file_uploader("Upload Prediction Excel", type=["xlsx","xls"])
851
  if up is not None:
852
  book = read_book_bytes(up.getvalue())
@@ -858,7 +858,7 @@ if st.session_state.app_step == "predict":
858
  go_btn = st.sidebar.button("Predict", type="primary", use_container_width=True)
859
  if st.sidebar.button("⬅ Back to Case Building", use_container_width=True): st.session_state.app_step="dev"; st.rerun()
860
 
861
- sticky_header("Prediction", "Upload a dataset with the feature columns (no **Ts**).")
862
 
863
  if go_btn and up is not None:
864
  book = read_book_bytes(up.getvalue()); name = list(book.keys())[0]
 
1
+ # app_tc.py — ST_Sonic_Tc (Compressional Slowness Tc)
2
 
3
  import io, json, os, base64, math
4
  from pathlib import Path
 
18
  from sklearn.metrics import mean_squared_error, mean_absolute_error
19
 
20
  # =========================
21
+ # Constants (Tc variant)
22
  # =========================
23
+ APP_NAME = "ST_Log_Sonic (Tc)"
24
+ TAGLINE = "Real-Time Compressional Slowness (Tc) Prediction"
25
 
26
+ # Defaults (overridden by tc_meta.json if present)
27
  FEATURES = [
28
  "WOB (klbf)",
29
  "Torque (kft.lbf)",
 
32
  "ROP (ft/h)",
33
  "Flow Rate (gpm)",
34
  ]
35
+ TARGET = "Tc (us/ft_Actual)"
36
+ PRED_COL = "Tc_Pred"
37
 
38
  MODELS_DIR = Path("models")
39
+ DEFAULT_MODEL = MODELS_DIR / "tc_model.joblib"
40
  MODEL_FALLBACKS = [MODELS_DIR / "model.joblib", MODELS_DIR / "model.pkl"]
41
  COLORS = {"pred": "#1f77b4", "actual": "#f2b702", "ref": "#5a5a5a"}
42
 
 
63
  .st-message-box.st-success { background-color: #d4edda; color: #155724; border-color: #c3e6cb; }
64
  .st-message-box.st-warning { background-color: #fff3cd; color: #856404; border-color: #ffeeba; }
65
  .st-message-box.st-error { background-color: #f8d7da; color: #721c24; border-color: #f5c6cb; }
66
+ .main .block-container { overflow: unset !IMPORTANT; }
67
+ div[data-testid="stVerticalBlock"] { overflow: unset !IMPORTANT; }
68
  div[data-testid="stExpander"] > details > summary {
69
  position: sticky; top: 0; z-index: 10; background: #fff; border-bottom: 1px solid #eee;
70
  }
 
152
  def _build_alias_map(canonical_features: list[str], target_name: str) -> dict:
153
  """
154
  Map common header variants -> the *canonical* names in canonical_features.
155
+ Whatever appears in canonical_features (from tc_meta.json) wins.
156
  """
157
  def pick(expected_list, variants):
158
  for v in variants:
 
181
  # Depth (plot only)
182
  "Depth (ft)": can_DEPTH, "Depth, ft": can_DEPTH, "Depth(ft)": can_DEPTH, "DEPTH, ft": can_DEPTH,
183
 
184
+ # Target family (Tc)
185
+ "Tc (us/ft_Actual)": target_name,
186
+ "Tc,us/ft_Actual": target_name,
187
+ "Tc, us/ft_Actual": target_name,
188
+ "Tc": target_name,
189
+ "TC_Actual": target_name,
190
+ "Tc (us/ft)_Actual": target_name,
191
  }
192
  return alias
193
 
 
365
  if do_autofit:
366
  _excel_autofit(writer, sheet, df)
367
  bio.seek(0)
368
+ fname = f"TC_Export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
369
  return bio.getvalue(), fname, order
370
 
371
  # --------- SIMPLE export UI ----------
 
390
  st.download_button(
391
  label="⬇️ Export Excel",
392
  data=b"",
393
+ file_name="TC_Export.xlsx",
394
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
395
  disabled=True,
396
  key=f"download_{phase_key}",
 
403
  st.download_button(
404
  "⬇️ Export Excel",
405
  data=(data or b""),
406
+ file_name=(fname or "TC_Export.xlsx"),
407
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
408
  disabled=(data is None),
409
  key=f"download_{phase_key}",
 
412
  # =========================
413
  # Cross plot (Matplotlib)
414
  # =========================
415
+ def cross_plot_static(actual, pred, xlabel="Actual Tc (µs/ft)", ylabel="Predicted Tc (µs/ft)"):
416
  a = pd.Series(actual, dtype=float)
417
  p = pd.Series(pred, dtype=float)
418
 
 
494
  legend_title_text=""
495
  )
496
  fig.update_xaxes(
497
+ title_text="Tc (μs/ft)",
498
  title_font=dict(size=20, family=BOLD_FONT, color="#000"),
499
  tickfont=dict(size=15, family=BOLD_FONT, color="#000"),
500
  side="top", range=[xmin, xmax],
 
587
 
588
  mpath = ensure_model()
589
  if not mpath:
590
+ st.error("Model not found. Upload models/tc_model.joblib (or set MODEL_URL).")
591
  st.stop()
592
  try:
593
  model = load_model(str(mpath))
 
595
  st.error(f"Failed to load model: {e}")
596
  st.stop()
597
 
598
+ # Load meta (prefer Tc-specific)
599
  meta = {}
600
+ meta_candidates = [MODELS_DIR / "tc_meta.json", MODELS_DIR / "meta.json"]
601
  meta_path = next((p for p in meta_candidates if p.exists()), None)
602
  if meta_path:
603
  try:
 
665
  # =========================
666
  if st.session_state.app_step == "intro":
667
  st.header("Welcome!")
668
+ st.markdown("This software is developed by *Smart Thinking AI-Solutions Team* to estimate **Compressional Slowness (Tc)** from drilling data.")
669
  st.subheader("How It Works")
670
  st.markdown(
671
  "1) **Upload your data to build the case and preview the model performance.** \n"
672
  "2) Click **Run Model** to compute metrics and plots. \n"
673
+ "3) **Proceed to Validation** (with actual Tc) or **Proceed to Prediction** (no Tc)."
674
  )
675
  if st.button("Start Showcase", type="primary"):
676
  st.session_state.app_step = "dev"; st.rerun()
 
767
  render_export_button(phase_key="dev")
768
 
769
  # =========================
770
+ # VALIDATION (with actual Tc)
771
  # =========================
772
  if st.session_state.app_step == "validate":
773
  st.sidebar.header("Validate the Model")
 
783
  if st.sidebar.button("⬅ Back to Case Building", use_container_width=True): st.session_state.app_step="dev"; st.rerun()
784
  if st.sidebar.button("Proceed to Prediction ▶", use_container_width=True): st.session_state.app_step="predict"; st.rerun()
785
 
786
+ sticky_header("Validate the Model", "Upload a dataset with the same **features** and **Tc** to evaluate performance.")
787
 
788
  if go_btn and up is not None:
789
  book = read_book_bytes(up.getvalue())
 
843
  df_centered_rounded(st.session_state.results["oor_tbl"])
844
 
845
  # =========================
846
+ # PREDICTION (no actual Tc)
847
  # =========================
848
  if st.session_state.app_step == "predict":
849
+ st.sidebar.header("Prediction (No Actual Tc)")
850
  up = st.sidebar.file_uploader("Upload Prediction Excel", type=["xlsx","xls"])
851
  if up is not None:
852
  book = read_book_bytes(up.getvalue())
 
858
  go_btn = st.sidebar.button("Predict", type="primary", use_container_width=True)
859
  if st.sidebar.button("⬅ Back to Case Building", use_container_width=True): st.session_state.app_step="dev"; st.rerun()
860
 
861
+ sticky_header("Prediction", "Upload a dataset with the feature columns (no **Tc**).")
862
 
863
  if go_btn and up is not None:
864
  book = read_book_bytes(up.getvalue()); name = list(book.keys())[0]