Files changed (1) hide show
  1. app.py +196 -39
app.py CHANGED
@@ -16,9 +16,9 @@ print("Loaded SCALE/MEAN/STD:", SCALE, MEAN, STD, flush=True)
16
 
17
  CLASS_NAMES = ["MMAT", "MLBT"]
18
 
19
-
20
-
21
- # ---- Preprocessing: Image -> (1, 32, 32, 1) normalized ----
22
  def preprocess(img: np.ndarray) -> np.ndarray:
23
  if img.ndim == 3 and img.shape[2] == 3:
24
  img_gray = np.dot(img[..., :3], [0.2989, 0.5870, 0.1140])
@@ -33,57 +33,214 @@ def preprocess(img: np.ndarray) -> np.ndarray:
33
  pil_img = pil_img.resize((32, 32), Image.BILINEAR)
34
  arr = np.array(pil_img).astype("float32")
35
 
36
- # Invert the global scaling to approximate original X
37
  arr_unscaled = arr / SCALE
38
-
39
- # Now apply the same normalization as during training
40
  arr_norm = (arr_unscaled - MEAN) / (STD + 1e-8)
41
-
42
  arr_norm = arr_norm[None, ..., None]
43
  return arr_norm
44
 
45
 
46
-
47
- # ---- Prediction function for Gradio ----
 
48
  def predict(img: np.ndarray):
49
  x = preprocess(img)
50
  raw = float(model.predict(x, verbose=0)[0, 0])
51
- print("Raw model output:", raw, flush=True)
52
-
53
- # raw ≈ P(MLBT) as in training
54
  prob_mlbt = raw
55
  prob_mmat = 1.0 - prob_mlbt
56
-
57
  return {"MLBT": prob_mlbt, "MMAT": prob_mmat}
58
 
59
 
60
 
61
-
62
-
63
- # ---- Gradio interface ----
64
- input_component = gr.Image(
65
- type="numpy",
66
- label="Jet image (grayscale or RGB, any size ≥ 32x32)"
67
- )
68
-
69
- output_component = gr.Label(
70
- num_top_classes=2,
71
- label="Predicted probabilities"
72
- )
73
-
74
- examples = [] # you can drop some example jet PNGs here later
75
-
76
- demo = gr.Interface(
77
- fn=predict,
78
- inputs=input_component,
79
- outputs=output_component,
80
- title="MLBT vs MMAT Jet Classifier (Small 32×32 CNN)",
81
- description=(
82
- "Upload a jet image (32×32 heatmap or larger) and this model "
83
- "predicts whether it came from the MLBT or MMAT energy-loss module."
84
- ),
85
- examples=examples
86
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  if __name__ == "__main__":
89
  demo.launch()
 
16
 
17
  CLASS_NAMES = ["MMAT", "MLBT"]
18
 
19
+ # ---------------------------------------------------------
20
+ # PREPROCESSING
21
+ # ---------------------------------------------------------
22
  def preprocess(img: np.ndarray) -> np.ndarray:
23
  if img.ndim == 3 and img.shape[2] == 3:
24
  img_gray = np.dot(img[..., :3], [0.2989, 0.5870, 0.1140])
 
33
  pil_img = pil_img.resize((32, 32), Image.BILINEAR)
34
  arr = np.array(pil_img).astype("float32")
35
 
 
36
  arr_unscaled = arr / SCALE
 
 
37
  arr_norm = (arr_unscaled - MEAN) / (STD + 1e-8)
 
38
  arr_norm = arr_norm[None, ..., None]
39
  return arr_norm
40
 
41
 
42
+ # ---------------------------------------------------------
43
+ # PREDICT FUNCTION
44
+ # ---------------------------------------------------------
45
  def predict(img: np.ndarray):
46
  x = preprocess(img)
47
  raw = float(model.predict(x, verbose=0)[0, 0])
 
 
 
48
  prob_mlbt = raw
49
  prob_mmat = 1.0 - prob_mlbt
 
50
  return {"MLBT": prob_mlbt, "MMAT": prob_mmat}
51
 
52
 
53
 
54
+ # ---------------------------------------------------------
55
+ # ABOUT PAGE — Flip-cards recreated in HTML/CSS
56
+ # ---------------------------------------------------------
57
+ about_html = """
58
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
59
+
60
+ <style>
61
+ .grid {
62
+ display: grid;
63
+ grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
64
+ gap: 16px;
65
+ margin-top: 20px;
66
+ }
67
+
68
+ .flip-card {
69
+ background: transparent;
70
+ width: 100%;
71
+ height: 230px;
72
+ perspective: 1400px;
73
+ cursor: pointer;
74
+ }
75
+
76
+ .flip-inner {
77
+ position: relative;
78
+ width: 100%;
79
+ height: 100%;
80
+ transition: transform 0.6s;
81
+ transform-style: preserve-3d;
82
+ }
83
+
84
+ .flip-card:hover .flip-inner {
85
+ transform: rotateY(180deg);
86
+ }
87
+
88
+ .flip-face {
89
+ position: absolute;
90
+ inset: 0;
91
+ border-radius: 12px;
92
+ backface-visibility: hidden;
93
+ display: flex;
94
+ flex-direction: column;
95
+ justify-content:center;
96
+ align-items:center;
97
+ padding: 14px;
98
+ text-align:center;
99
+ box-shadow: 0 6px 18px rgba(16,24,40,0.1);
100
+ }
101
+
102
+ .front {
103
+ background:white;
104
+ font-size:26px;
105
+ font-weight:800;
106
+ color:#0f172a;
107
+ }
108
+
109
+ .front small {
110
+ margin-top:8px;
111
+ font-size:12px;
112
+ color:#64748b;
113
+ font-weight:500;
114
+ }
115
+
116
+ .back {
117
+ background: linear-gradient(135deg,#7c3aed,#2563eb);
118
+ color:white;
119
+ transform: rotateY(180deg);
120
+ font-size:14px;
121
+ line-height:1.35;
122
+ }
123
+
124
+ h1 {
125
+ text-align:center;
126
+ color:#5b21b6;
127
+ font-size:32px;
128
+ }
129
+
130
+ h2 {
131
+ text-align:center;
132
+ color:#5b21b6;
133
+ margin-top:25px;
134
+ }
135
+ </style>
136
+
137
+
138
+ <h1> Learn more about high-energy physics! ⚛️ </h1>
139
+ <h2> 🔍 Key Concepts </h2>
140
+
141
+ <div class="grid">
142
+ <!-- QGP -->
143
+ <div class="flip-card">
144
+ <div class="flip-inner">
145
+ <div class="flip-face front">QGP <small>click to learn more</small></div>
146
+ <div class="flip-face back">
147
+ <b>Quark–Gluon Plasma (QGP)</b><br><br>
148
+ A super-hot state of matter where quarks and gluons move freely.<br><br>
149
+ Helps us understand conditions microseconds after the Big Bang.
150
+ </div>
151
+ </div>
152
+ </div>
153
+
154
+ <!-- Pb-Pb -->
155
+ <div class="flip-card">
156
+ <div class="flip-inner">
157
+ <div class="flip-face front">Pb–Pb <small>click to learn more</small></div>
158
+ <div class="flip-face back">
159
+ <b>Lead–Lead Collisions</b><br><br>
160
+ High-energy lead nuclei collisions that create QGP.<br><br>
161
+ Lets us study how jets lose energy in extreme matter.
162
+ </div>
163
+ </div>
164
+ </div>
165
+
166
+ <!-- Jet -->
167
+ <div class="flip-card">
168
+ <div class="flip-inner">
169
+ <div class="flip-face front">Jet <small>click to learn more</small></div>
170
+ <div class="flip-face back">
171
+ <b>Jets & Jet Quenching</b><br><br>
172
+ Sprays of particles created during collisions.<br><br>
173
+ Energy loss → reveals QGP properties.
174
+ </div>
175
+ </div>
176
+ </div>
177
+
178
+ <!-- αₛ -->
179
+ <div class="flip-card">
180
+ <div class="flip-inner">
181
+ <div class="flip-face front">αₛ <small>click to learn more</small></div>
182
+ <div class="flip-face back">
183
+ <b>Strong Coupling Constant (αₛ)</b><br><br>
184
+ Measures how strongly quarks bind together.<br><br>
185
+ Different αₛ values help model jet energy loss.
186
+ </div>
187
+ </div>
188
+ </div>
189
+
190
+ <!-- Q0 -->
191
+ <div class="flip-card">
192
+ <div class="flip-inner">
193
+ <div class="flip-face front">Q₀ <small>click to learn more</small></div>
194
+ <div class="flip-face back">
195
+ <b>Virtuality Scale (Q₀)</b><br><br>
196
+ Determines how quantum or classical jet evolution is.<br><br>
197
+ Controls which processes dominate in QGP.
198
+ </div>
199
+ </div>
200
+ </div>
201
+
202
+ <!-- MATTER -->
203
+ <div class="flip-card">
204
+ <div class="flip-inner">
205
+ <div class="flip-face front">MATTER <small>click to learn more</small></div>
206
+ <div class="flip-face back">
207
+ <b>MATTER Model</b><br><br>
208
+ Describes energy loss via radiation + elastic collisions.<br><br>
209
+ Represents early jet evolution.
210
+ </div>
211
+ </div>
212
+ </div>
213
+
214
+ <!-- MATTER-LBT -->
215
+ <div class="flip-card">
216
+ <div class="flip-inner">
217
+ <div class="flip-face front">MATTER–LBT <small>click to learn more</small></div>
218
+ <div class="flip-face back">
219
+ <b>MATTER–LBT Model</b><br><br>
220
+ Hybrid model combining radiation + medium scattering.<br><br>
221
+ Simulates realistic QGP interactions.
222
+ </div>
223
+ </div>
224
+ </div>
225
+
226
+ </div>
227
+ """
228
+
229
+
230
+ # ---------------------------------------------------------
231
+ # FINAL GRADIO APP WITH TABS
232
+ # ---------------------------------------------------------
233
+ with gr.Blocks() as demo:
234
+ gr.Markdown("<h1 style='text-align:center;'>MLBT vs MMAT Jet Classifier</h1>")
235
+
236
+ with gr.Tabs():
237
+ with gr.Tab("🔬 Classifier"):
238
+ input_component = gr.Image(type="numpy", label="Upload a jet image")
239
+ output_component = gr.Label(num_top_classes=2, label="Predicted probabilities")
240
+ input_component.change(predict, inputs=input_component, outputs=output_component)
241
+
242
+ with gr.Tab("📘 About"):
243
+ gr.HTML(about_html)
244
 
245
  if __name__ == "__main__":
246
  demo.launch()