Ansaribinhyder commited on
Commit
6930d8f
·
1 Parent(s): 4a1ae17

added new code for two tester data comparision

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