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

Revert back to original

Browse files
Files changed (3) hide show
  1. app.py +62 -136
  2. templates/index.html +4 -4
  3. templates/plot.html +4 -4
app.py CHANGED
@@ -7,43 +7,31 @@ import os
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,100 +40,68 @@ def process_golden_file(golden_file):
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,67 +109,49 @@ def generate_plot(col):
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,28 +160,16 @@ def download_comparison():
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)
 
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
  "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
  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
  """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,12 +139,12 @@
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">
@@ -192,4 +192,4 @@
192
  {% endif %}
193
 
194
  </body>
195
- </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">
 
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,12 +84,12 @@
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">
@@ -136,4 +136,4 @@
136
  {% endif %}
137
 
138
  </body>
139
- </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">
 
136
  {% endif %}
137
 
138
  </body>
139
+ </html> -->