Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -19,23 +19,18 @@ from sklearn.metrics import mean_squared_error, mean_absolute_error
|
|
| 19 |
# =========================
|
| 20 |
# Constants (Ts variant)
|
| 21 |
# =========================
|
| 22 |
-
APP_NAME = "
|
| 23 |
TAGLINE = "Real-Time Shear Slowness (Ts) Prediction"
|
| 24 |
|
| 25 |
-
#
|
| 26 |
-
FEATURES = [
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
"
|
| 30 |
-
|
| 31 |
-
"ROP(ft/h)",
|
| 32 |
-
"Flow Rate, gpm",
|
| 33 |
-
]
|
| 34 |
-
TARGET = "Ts,us/ft_Actual" # actual Ts column in your sheets
|
| 35 |
-
PRED_COL = "Ts_Pred" # predicted Ts column we’ll add
|
| 36 |
|
| 37 |
MODELS_DIR = Path("models")
|
| 38 |
-
DEFAULT_MODEL = MODELS_DIR / "ts_model.joblib"
|
| 39 |
MODEL_FALLBACKS = [MODELS_DIR / "model.joblib", MODELS_DIR / "model.pkl"]
|
| 40 |
COLORS = {"pred": "#1f77b4", "actual": "#f2b702", "ref": "#5a5a5a"}
|
| 41 |
|
|
@@ -226,24 +221,49 @@ def _excel_engine() -> str:
|
|
| 226 |
|
| 227 |
def _normalize_columns(df: pd.DataFrame) -> pd.DataFrame:
|
| 228 |
out = df.copy()
|
| 229 |
-
out.columns = [str(c).strip() for c in out.columns]
|
| 230 |
|
| 231 |
-
#
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
"
|
| 238 |
-
"
|
| 239 |
-
"
|
| 240 |
-
"
|
| 241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 242 |
"Depth(ft)": "Depth, ft",
|
|
|
|
| 243 |
}
|
| 244 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 245 |
return out
|
| 246 |
|
|
|
|
| 247 |
def _excel_safe_name(name: str) -> str:
|
| 248 |
bad = '[]:*?/\\'
|
| 249 |
safe = ''.join('_' if ch in bad else ch for ch in str(name))
|
|
@@ -639,7 +659,11 @@ except Exception as e:
|
|
| 639 |
# ---------- Load meta (optional) ----------
|
| 640 |
meta = {}
|
| 641 |
# Prefer a Ts-specific meta, fall back to a generic one if present
|
| 642 |
-
meta_candidates = [
|
|
|
|
|
|
|
|
|
|
|
|
|
| 643 |
meta_path = next((p for p in meta_candidates if p.exists()), None)
|
| 644 |
if meta_path:
|
| 645 |
try:
|
|
|
|
| 19 |
# =========================
|
| 20 |
# Constants (Ts variant)
|
| 21 |
# =========================
|
| 22 |
+
APP_NAME = "ST_Log_Sonic(Ts)"
|
| 23 |
TAGLINE = "Real-Time Shear Slowness (Ts) Prediction"
|
| 24 |
|
| 25 |
+
# Keep your drilling features the same (we'll normalize header variants below)
|
| 26 |
+
FEATURES = ["WOB(klbf)", "TORQUE(kft.lbf)", "SPP(psi)", "RPM(1/min)", "ROP(ft/h)", "Flow Rate, gpm"]
|
| 27 |
+
|
| 28 |
+
# Target and pred column for Ts
|
| 29 |
+
TARGET = "Ts" # we'll map your file's "Ts,us/ft_Actual" → "Ts"
|
| 30 |
+
PRED_COL = "Ts_Pred"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
MODELS_DIR = Path("models")
|
| 33 |
+
DEFAULT_MODEL = MODELS_DIR / "ts_model.joblib"
|
| 34 |
MODEL_FALLBACKS = [MODELS_DIR / "model.joblib", MODELS_DIR / "model.pkl"]
|
| 35 |
COLORS = {"pred": "#1f77b4", "actual": "#f2b702", "ref": "#5a5a5a"}
|
| 36 |
|
|
|
|
| 221 |
|
| 222 |
def _normalize_columns(df: pd.DataFrame) -> pd.DataFrame:
|
| 223 |
out = df.copy()
|
|
|
|
| 224 |
|
| 225 |
+
# Trim and collapse inner spaces like ", " → ", " consistently
|
| 226 |
+
out.columns = [str(c).strip().replace(" ,", ",").replace(", ", ", ").replace(" ", " ") for c in out.columns]
|
| 227 |
+
|
| 228 |
+
# Canonical rename map: map what you have → what the app expects
|
| 229 |
+
rename_map = {
|
| 230 |
+
# Drilling features
|
| 231 |
+
"WOB, klbf": "WOB(klbf)",
|
| 232 |
+
"WOB (klbf)": "WOB(klbf)",
|
| 233 |
+
"WOB( klbf)": "WOB(klbf)",
|
| 234 |
+
"WOB(klbf)": "WOB(klbf)",
|
| 235 |
+
|
| 236 |
+
"Torque(kft.lbf)": "TORQUE(kft.lbf)",
|
| 237 |
+
"TORQUE(kft.lbf)": "TORQUE(kft.lbf)",
|
| 238 |
+
|
| 239 |
+
"SPP(psi)": "SPP(psi)",
|
| 240 |
+
"RPM(1/min)": "RPM(1/min)",
|
| 241 |
+
"ROP(ft/h)": "ROP(ft/h)",
|
| 242 |
+
"Flow Rate, gpm": "Flow Rate, gpm",
|
| 243 |
+
|
| 244 |
+
# Target column variants coming from your file
|
| 245 |
+
"Ts,us/ft_Actual": "Ts",
|
| 246 |
+
"Ts, us/ft_Actual": "Ts",
|
| 247 |
+
"TS_Actual": "Ts",
|
| 248 |
+
"Ts (us/ft)_Actual":"Ts",
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
# Also keep Depth variants tidy (used for Y axis only)
|
| 252 |
+
depth_variants = {
|
| 253 |
+
"Depth, ft": "Depth, ft",
|
| 254 |
"Depth(ft)": "Depth, ft",
|
| 255 |
+
"DEPTH, ft": "Depth, ft",
|
| 256 |
}
|
| 257 |
+
|
| 258 |
+
# Build final mapping
|
| 259 |
+
final_map = {**depth_variants}
|
| 260 |
+
# Only add keys that actually exist to avoid KeyErrors
|
| 261 |
+
final_map.update({k: v for k, v in rename_map.items() if k in out.columns})
|
| 262 |
+
|
| 263 |
+
out = out.rename(columns=final_map)
|
| 264 |
return out
|
| 265 |
|
| 266 |
+
|
| 267 |
def _excel_safe_name(name: str) -> str:
|
| 268 |
bad = '[]:*?/\\'
|
| 269 |
safe = ''.join('_' if ch in bad else ch for ch in str(name))
|
|
|
|
| 659 |
# ---------- Load meta (optional) ----------
|
| 660 |
meta = {}
|
| 661 |
# Prefer a Ts-specific meta, fall back to a generic one if present
|
| 662 |
+
meta_candidates = [
|
| 663 |
+
MODELS_DIR / "ts_meta.json", # ← add this
|
| 664 |
+
MODELS_DIR / "meta.json",
|
| 665 |
+
MODELS_DIR / "ym_meta.json",
|
| 666 |
+
]
|
| 667 |
meta_path = next((p for p in meta_candidates if p.exists()), None)
|
| 668 |
if meta_path:
|
| 669 |
try:
|