Spaces:
Sleeping
Sleeping
File size: 9,423 Bytes
2546160 3c118cd 9b40395 702e044 815a086 6930d8f 2546160 6930d8f 2546160 9b40395 6930d8f 9b40395 2546160 6930d8f 58bde6b 815a086 2546160 9b40395 6930d8f 815a086 6930d8f 815a086 6930d8f 815a086 58bde6b 9b40395 6930d8f 815a086 2546160 9b40395 6930d8f 2546160 58bde6b 6930d8f 9b40395 6930d8f 9f89845 6930d8f 9b40395 6930d8f 9b40395 6930d8f 9b40395 6930d8f 9b40395 6930d8f 58bde6b 6930d8f 815a086 6930d8f 815a086 6930d8f 815a086 6930d8f 815a086 6930d8f 815a086 6930d8f 815a086 6930d8f 815a086 6930d8f 815a086 9b40395 815a086 6930d8f 815a086 702e044 6930d8f 2546160 6930d8f 2546160 aba2e4d 2546160 9b40395 6930d8f 2546160 6930d8f 2546160 6930d8f 9b40395 2546160 6930d8f 2546160 6930d8f 815a086 6930d8f 9b40395 6930d8f 815a086 3c118cd 2546160 6930d8f 2546160 3c118cd 6930d8f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | from flask import Flask, render_template, request, send_file, redirect, url_for
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import io
import os
app = Flask(__name__)
# --- Cache updated to hold two test files ---
data_cache = {
"df1": None, # Golden Data
"df2_temp": None, # Test 1 Data
"df3_temp": None, # Test 2 Data
"limits": {},
"cols": [],
"golden_loaded": False,
"test1_loaded": False,
"test2_loaded": False,
"comparison_file": None
}
# ----------------------------------------------
def process_golden_file(golden_file):
"""Load Golden data and extract limits."""
# Use pandas ExcelFile to read multiple times from the file-like object
xls = pd.ExcelFile(golden_file)
limits_df1 = pd.read_excel(xls, nrows=4)
df1 = pd.read_excel(xls) # Read the entire sheet again for data
df1 = df1.drop([0, 1, 2, 3])
df1 = df1.apply(pd.to_numeric, errors="coerce")
limits_df1 = limits_df1.drop([0])
ignore_cols = ["SITE_NUM", "PART_ID", "PASSFG", "SOFT_BIN", "T_TIME", "TEST_NUM"]
# Identify columns to plot/analyze: must contain '_' and not be in ignore_cols
cols_to_plot = [col for col in limits_df1.columns if "_" in str(col) and col not in ignore_cols]
# Drop ignore columns from limits df to only get limits for relevant parameters
limits_df1_filtered = limits_df1.drop(columns=ignore_cols, errors='ignore')
limits = {
col: {"LL": limits_df1_filtered.iloc[0][col], "UL": limits_df1_filtered.iloc[1][col]}
for col in limits_df1_filtered.columns
if pd.notna(limits_df1_filtered.iloc[0][col]) or pd.notna(limits_df1_filtered.iloc[1][col])
}
data_cache.update({
"df1": df1,
"limits": limits,
"cols": cols_to_plot,
"golden_loaded": True
})
return "Golden data loaded successfully!"
def process_test_file(test_file):
"""Load Test data."""
df_test = pd.read_excel(test_file)
df_test = df_test.drop([0, 1, 2, 3])
df_test = df_test.apply(pd.to_numeric, errors="coerce")
return df_test
# --- Comparison function updated for two test files ---
def generate_comparison_excel():
"""Generate comparison Excel (mean, std, min, max for Golden, Test 1, and Test 2)."""
df1 = data_cache["df1"]
df2 = data_cache["df2_temp"]
df3 = data_cache["df3_temp"]
ignore_cols = ["SITE_NUM", "PART_ID", "PASSFG", "SOFT_BIN", "T_TIME", "TEST_NUM"]
# Use columns identified during Golden file processing
common_cols = data_cache["cols"]
summary = []
for col in common_cols:
g_mean, t1_mean, t2_mean = df1[col].mean(), df2.get(col, pd.Series()).mean(), df3.get(col, pd.Series()).mean()
g_std, t1_std, t2_std = df1[col].std(), df2.get(col, pd.Series()).std(), df3.get(col, pd.Series()).std()
g_min, t1_min, t2_min = df1[col].min(), df2.get(col, pd.Series()).min(), df3.get(col, pd.Series()).min()
g_max, t1_max, t2_max = df1[col].max(), df2.get(col, pd.Series()).max(), df3.get(col, pd.Series()).max()
# Calculate differences relative to Golden mean
diff1 = t1_mean - g_mean if pd.notna(t1_mean) and pd.notna(g_mean) else np.nan
diff2 = t2_mean - g_mean if pd.notna(t2_mean) and pd.notna(g_mean) else np.nan
summary.append([
col, g_mean, t1_mean, t2_mean, diff1, diff2,
g_std, t1_std, t2_std,
g_min, t1_min, t2_min,
g_max, t1_max, t2_max
])
comp_df = pd.DataFrame(summary, columns=[
"Parameter", "Golden_Mean", "Test1_Mean", "Test2_Mean", "Test1_Mean_Diff", "Test2_Mean_Diff",
"Golden_Std", "Test1_Std", "Test2_Std",
"Golden_Min", "Test1_Min", "Test2_Min",
"Golden_Max", "Test1_Max", "Test2_Max"
])
path = "comparison_result.xlsx"
comp_df.to_excel(path, index=False)
data_cache["comparison_file"] = path
# -------------------------------------------------------------
# --- Plot function updated for two test files ---
def generate_plot(col):
"""Generate and return a plot comparing Golden vs Test 1 vs Test 2."""
df1, df2, df3 = data_cache["df1"], data_cache.get("df2_temp"), data_cache.get("df3_temp")
limits = data_cache["limits"]
plt.figure(figsize=(10, 6)) # Increased size for better visibility
# Golden Plot
x1 = np.arange(1, len(df1[col]) + 1)
plt.plot(x1, df1[col], 'o-', label="Golden", color='blue', alpha=0.7)
# Test 1 Plot
if df2 is not None and col in df2.columns:
x2 = np.arange(1, len(df2[col]) + 1)
plt.plot(x2, df2[col], 's--', label="Test 1", color='red', alpha=0.7)
# Test 2 Plot
if df3 is not None and col in df3.columns:
x3 = np.arange(1, len(df3[col]) + 1)
plt.plot(x3, df3[col], 'x:', label="Test 2", color='purple', alpha=0.8)
# Limits Plot
if col in limits:
ll, ul = limits[col].get("LL"), limits[col].get("UL")
if pd.notna(ll):
plt.axhline(ll, color='green', linestyle='--', label='LL', linewidth=1)
if pd.notna(ul):
plt.axhline(ul, color='orange', linestyle='--', label='UL', linewidth=1)
plt.title(f"Parameter: {col}")
plt.xlabel("Part # (sequence)")
plt.ylabel("Value")
plt.legend(fontsize='small', loc='best')
plt.grid(True, linestyle='--', alpha=0.5)
# Set x-ticks based on the largest dataset (assuming Golden is the reference)
max_len = len(df1[col])
if max_len > 1:
plt.xticks(np.arange(1, max_len + 1, max(1, max_len // 10))) # Show max 10 ticks
plt.tight_layout()
buf = io.BytesIO()
plt.savefig(buf, format='png', bbox_inches='tight')
buf.seek(0)
plt.close()
return buf
# -------------------------------------------------------------
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
# 1. Upload Golden file
if not data_cache["golden_loaded"]:
golden_file = request.files.get("golden_file")
if not golden_file:
return render_template("index.html", error="Please upload the Golden file.")
try:
process_golden_file(golden_file)
return redirect(url_for("index"))
except Exception as e:
return render_template("index.html", error=f"Error loading Golden file: {e}")
# 2. Upload Test 1 file
elif not data_cache["test1_loaded"]:
test1_file = request.files.get("test1_file")
if not test1_file:
return render_template("index.html", error="Please upload the first Test file (Test 1).", **data_cache)
try:
df2 = process_test_file(test1_file)
data_cache["df2_temp"] = df2
data_cache["test1_loaded"] = True
return redirect(url_for("index"))
except Exception as e:
return render_template("index.html", error=f"Error processing Test 1 file: {e}", **data_cache)
# 3. Upload Test 2 file
elif not data_cache["test2_loaded"]:
test2_file = request.files.get("test2_file")
if not test2_file:
return render_template("index.html", error="Please upload the second Test file (Test 2).", **data_cache)
try:
df3 = process_test_file(test2_file)
data_cache["df3_temp"] = df3
data_cache["test2_loaded"] = True
# Generate comparison and move to plot view after all files are loaded
generate_comparison_excel()
return render_template(
"plot.html",
cols=data_cache["cols"],
file_ready=True
)
except Exception as e:
return render_template("index.html", error=f"Error processing Test 2 file: {e}", **data_cache)
return render_template("index.html", **data_cache)
@app.route("/plot_image/<col>")
def plot_image(col):
# df2 and df3 are checked inside generate_plot
if data_cache.get("df1") is None:
return "No Golden data loaded."
buf = generate_plot(col)
return send_file(buf, mimetype="image/png")
@app.route("/download_comparison")
def download_comparison():
"""Download comparison Excel file."""
path = data_cache.get("comparison_file")
if path and os.path.exists(path):
return send_file(path, as_attachment=True, download_name="three_way_comparison_result.xlsx")
return "No comparison file available. Please upload all data first."
@app.route("/reset_golden")
def reset_golden():
"""Reset all data."""
global data_cache
if data_cache.get("comparison_file") and os.path.exists(data_cache["comparison_file"]):
os.remove(data_cache["comparison_file"])
data_cache = {
"df1": None, "df2_temp": None, "df3_temp": None,
"limits": {}, "cols": [],
"golden_loaded": False, "test1_loaded": False, "test2_loaded": False,
"comparison_file": None
}
return redirect(url_for("index"))
if __name__ == "__main__":
# Ensure a local directory exists for comparison file (optional but good practice)
# if not os.path.exists("temp"):
# os.makedirs("temp")
app.run(host="0.0.0.0", port=7860, debug=True) |