Walnut Shell Concrete: Meta-analysis + Constraints + MCDA + LCA/Cost + Weight Sensitivity Codes

Read full text
Authors: Sadık Alper Yildizel
Cited by: 0

Abstract

#!/usr/bin/env python# -*- coding: utf-8 -*- """Walnut Shell Concrete: Meta-analysis + Constraints + MCDA + LCA/Cost + Weight SensitivityCode-only pipeline extracted from the working notebook (no narrative cells). Usage (Windows): python analysis_pipeline.py --input_xlsx "C:\\path\\Durability.xlsx" --out_dir "C:\\path\\Meta_Results"""" import argparsefrom pathlib import Path def parse_args(): p = argparse.ArgumentParser() p.add_argument("--input_xlsx", required=True, help="Path to Durability.xlsx") p.add_argument("--out_dir", required=True, help="Output directory for CSV/figures") p.add_argument("--n_boot", type=int, default=2000, help="Bootstrap iterations (where applicable)") p.add_argument("--seed", type=int, default=42, help="Random seed") return p.parse_args() args = parse_args()out_dir = Path(args.out_dir)out_dir.mkdir(parents=True, exist_ok=True)import osos.chdir(out_dir) # write all outputs into out_dir import pandas as pdfrom pathlib import Path # 1) Dosya yolu (Windows)file_path = Path(args.input_xlsx) # 2) Dosya var mı kontrolprint("File exists:", file_path.exists())print("Path:", file_path) # 3) Tüm sheet'leri okuxls = pd.ExcelFile(file_path)print("Sheets:", xls.sheet_names) # 4) Her sheet'i ayrı df olarak aldata = {sh: pd.read_excel(file_path, sheet_name=sh) for sh in xls.sheet_names} # 5) İlk bakış: her sheet'in boyutu ve ilk 5 satırfor sh, df in data.items(): print("\n" + "="*70) print(f"Sheet: {sh} | shape: {df.shape}") print(df.head()) import pandas as pdimport numpy as npfrom pathlib import Path file_path = Path(args.input_xlsx) # 1) Tüm sheet'leri okusheets = pd.read_excel(file_path, sheet_name=None)print("Sheets:", list(sheets.keys())) def parse_block_sheet(df, metric_name): """ Excel sayfasında blok blok ilerleyen yapıyı parse eder: - Başlık satırları: (x=NaN & y=string) veya (x=string & y=string) - Veri satırları: x ve y sayısal Çıktı: WS_% , value , study , metric """ df = df.copy() df.columns = [f"c{i}" for i in range(df.shape[1])] # Aday x ve y kolonları: # çoğu sayfada x=c0, y=c1 (NWA/NT/NU) # bazı sayfada normalized c2 (Density/UPV/T/WA) ama biz şimdilik normalize sheet'leri hedefliyoruz xcol, ycol = "c0", "c1" rows = [] current_study = None for _, r in df.iterrows(): x = r.get(xcol, np.nan) y = r.get(ycol, np.nan) # Header/study satırı yakalama # Örn: x NaN, y "Boukhelkhal et al. (2023)" gibi if (pd.isna(x) and isinstance(y, str) and y.strip()): current_study = y.strip() continue # Bazı sayfalarda "X-Değerleri Hilal et al (2020) FW" gibi başlık x'te olabiliyor if (isinstance(x, str) and "X" in x and isinstance(y, str) and y.strip()): current_study = y.strip() continue # Sayısal veri satırı x_num = pd.to_numeric(x, errors="coerce") y_num = pd.to_numeric(y, errors="coerce") if pd.notna(x_num) and pd.notna(y_num): rows.append({ "WS_%": float(x_num), "value": float(y_num), "study": current_study if current_study else "Unknown", "metric": metric_name }) out = pd.DataFrame(rows).sort_values(["metric","study","WS_%"]).reset_index(drop=True) return out # 2) Normalize sayfaları parse et (meta-regresyon için ideal)df_ND = parse_block_sheet(sheets["ND"], "Density_norm")df_NU = parse_block_sheet(sheets["NU"], "UPV_norm")df_NWA = parse_block_sheet(sheets["NWA"], "WaterAbsorption_norm")df_NT = parse_block_sheet(sheets["NT"], "ThermalConductivity_norm") # 3) Hepsini birleştir (long format)df_long = pd.concat([df_ND, df_NU, df_NWA, df_NT], ignore_index=True) print("Long df shape:", df_long.shape)print(df_long.head(20)) print("\nUnique metrics:", df_long["metric"].unique())print("Unique studies (first 15):", df_long["study"].unique()[:15]) import pandas as pdimport numpy as np def parse_block_sheet(df, metric_name, xcol_idx=0, ycol_idx=1): df = df.copy() df.columns = [f"c{i}" for i in range(df.shape[1])] xcol, ycol = f"c{xcol_idx}", f"c{ycol_idx}" rows = [] current_study = None for _, r in df.iterrows(): x = r.get(xcol, np.nan) y = r.get(ycol, np.nan) # study/header satırı if (pd.isna(x) and isinstance(y, str) and y.strip()): current_study = y.strip() continue if (isinstance(x, str) and "X" in x and isinstance(y, str) and y.strip()): current_study = y.strip() continue # veri satırı x_num = pd.to_numeric(x, errors="coerce") y_num = pd.to_numeric(y, errors="coerce") if pd.notna(x_num) and pd.notna(y_num): rows.append({ "WS_%": float(x_num), "value": float(y_num), "study": current_study if current_study else "Unknown", "metric": metric_name }) return pd.DataFrame(rows).sort_values(["study","WS_%"]).reset_index(drop=True) # Normalize metriklerdf_ND = parse_block_sheet(sheets["ND"], "Density_norm")df_NU = parse_block_sheet(sheets["NU"], "UPV_norm")df_NWA = parse_block_sheet(sheets["NWA"], "WaterAbsorption_norm")df_NT = parse_block_sheet(sheets["NT"], "ThermalConductivity_norm") # Ham metriklerdf_D = parse_block_sheet(sheets["Density"], "Density_raw")df_U = parse_block_sheet(sheets["UPV"], "UPV_raw")df_WA = parse_block_sheet(sheets["WA"], "WaterAbsorption_raw")df_T = parse_block_sheet(sheets["T"], "ThermalConductivity_raw") # Hepsini birleştirdf_all = pd.concat( [df_D, df_U, df_WA, df_T, df_ND, df_NU, df_NWA, df_NT], ignore_index=True) print("df_all shape:", df_all.shape)print("Unique metrics:", df_all["metric"].unique())print("Number of studies:", df_all["study"].nunique()) print(df_all.head(20)) # Her (study, metric) grubunda WS=0 var mı?check0 = (df_all.assign(is0=df_all["WS_%"].eq(0)) .groupby(["study","metric"])["is0"] .any() .reset_index(name="has_WS0")) print("Total groups:", check0.shape[0])print("Groups without WS=0:", (check0["has_WS0"]==False).sum()) print(check0[check0["has_WS0"]==False]) import numpy as np # 1) Her (study, metric) için baseline (WS=0) değerini çekbaseline = (df_all[df_all["WS_%"].eq(0)] .groupby(["study","metric"])["value"] .mean() .reset_index() .rename(columns={"value":"baseline_value"})) # 2) baseline'ı df_all'a ekledf_lnr = df_all.merge(baseline, on=["study","metric"], how="left") # 3) lnRR hesapla (WS=0 için lnRR=0 olur)df_lnr["lnRR"] = np.log(df_lnr["value"] / df_lnr["baseline_value"]) # 4) lnRR üretilemeyen satırlar (baseline yok) var mı?missing = df_lnr["baseline_value"].isna().sum()print("Rows with missing baseline:", missing) print(df_lnr.head(20)) ex = df_lnr[df_lnr["metric"].eq("Density_raw")].copy()print("Density_raw lnRR summary:")print(ex.groupby("WS_%")["lnRR"].mean().reset_index().head(10)) # 1-2 örnek çalışma çizimport matplotlib.pyplot as plt plt.figure(figsize=(6,4), dpi=150)for st in ex["study"].unique()[:3]: tmp = ex[ex["study"]==st] plt.plot(tmp["WS_%"], tmp["lnRR"], marker="o", label=st)plt.xlabel("WS_%")plt.ylabel("lnRR (Density)")plt.legend(fontsize=7)plt.tight_layout()plt.show() # WS=0 olmayan (study, metric) grupları listeleno0 = (df_lnr[df_lnr["baseline_value"].isna()] .groupby(["study","metric"])["WS_%"] .agg(["count","min","max", list]) .reset_index() .sort_values(["metric","study"])) print(no0)print("Number of missing-baseline groups:", no0.shape[0])print("Number of rows affected:", df_lnr["baseline_value"].isna().sum()) df_primary = df_lnr.dropna(subset=["baseline_value"]).copy()print("Primary shape:", df_primary.shape) # İstersen CSV olarak kaydetout_csv = str(Path(args.out_dir)/"df_primary_lnRR.csv")df_primary.to_csv(out_csv, index=False)print("Saved:", out_csv) print(df_primary.head()) import numpy as npimport pandas as pdimport matplotlib.pyplot as plt def bootstrap_polyfit(x, y, deg=2, n_boot=2000, seed=42): rng = np.random.default_rng(seed) coefs = [] n = len(x) for _ in range(n_boot): idx = rng.integers(0, n, n) xb, yb = x[idx], y[idx] try: c = np.polyfit(xb, yb, deg) coefs.append(c) except: continue return np.array(coefs) def poly_predict(coefs, xgrid): # coefs shape: (n_boot, deg+1) preds = np.vstack([np.polyval(c, xgrid) for c in coefs]) return preds metrics = df_primary["metric"].unique()xgrid = np.linspace(0, 40, 161) results = [] for m in metrics: d = df_primary[df_primary["metric"]==m] x = d["WS_%"].to_numpy() y = d["lnRR"].to_numpy() # bootstrap coefs = bootstrap_polyfit(x, y, deg=2, n_boot=2000) preds = poly_predict(coefs, xgrid) y_med = np.median(preds, axis=0) y_lo = np.percentile(preds, 2.5, axis=0) y_hi = np.percentile(preds, 97.5, axis=0) # tabloya kaydet tmp = pd.DataFrame({ "metric": m, "WS_%": xgrid, "lnRR_median": y_med, "lnRR_ci2p5": y_lo, "lnRR_ci97p5": y_hi }) results.append(tmp) # plot (tek figür) plt.figure(figsize=(6,4), dpi=150) plt.scatter(x, y, s=15) plt.plot(xgrid, y_med) plt.fill_between(xgrid, y_lo, y_hi, alpha=0.2) plt.xlabel("Walnut shell replacement (%)") plt.ylabel("lnRR") plt.title(m) plt.tight_layout() plt.show() df_meta_curve = pd.concat(results, ignore_index=True)print(df_meta_curve.head()) import numpy as npimport pandas as pdimport matplotlib.pyplot as plt def anchored_bootstrap_fit(x, y, n_boot=2000, seed=42): """ lnRR = a*WS + b*WS^2 (intercept = 0) bootstrap ile (a,b) dağılımı döndürür """ rng = np.random.default_rng(seed) coefs = [] n = len(x) X = np.column_stack([x, x**2]) for _ in range(n_boot): idx = rng.integers(0, n, n) Xb, yb = X[idx]

Fields of Study & Subjects

Concrete and Cement Materials Research Innovative concrete reinforcement materials Civil and Structural Engineering Research

Publication details

Journal / source
Zenodo (CERN European Organization for Nuclear Research)
Publication date
17 February 2026
Language
EN
Document type
Book