mattbitzesty commited on
Commit
194b113
·
verified ·
1 Parent(s): f69e0e1

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +36 -7
app.py CHANGED
@@ -175,29 +175,58 @@ def _pyramid_for_ingredient(model, heads, engine, smiles, cas, objective_dim):
175
  return pyr
176
 
177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  def predict(arm_label, rows, progress=gr.Progress()):
179
- rows = [r for r in rows if r and r[0]]
180
- if not rows:
181
- return None, "Add at least one ingredient."
 
182
  try:
183
  model, heads, engine, resolved, objective_dim = _load_arm(arm_label)
184
  except Exception as e:
185
  return None, f"Model load failed: {e}"
186
 
187
  mats = {label: (sm, cas) for label, sm, cas in _materials()}
188
- total_w = sum(float(r[1] or 0) for r in rows) or 1.0
189
  blend = np.zeros(objective_dim, dtype=np.float64) # (objective_dim,) tier-summed
190
  tier_blend = np.zeros((3, objective_dim), dtype=np.float64)
191
  used = []
192
- for r in progress.tqdm(rows, desc="Encoding"):
193
- label, conc = r[0], float(r[1] or 0)
194
- if label not in mats or conc <= 0:
 
195
  continue
196
  sm, cas = mats[label]
197
  pyr = _pyramid_for_ingredient(model, heads, engine, sm, cas, objective_dim) # (3, D)
198
  w = conc / total_w
199
  tier_blend += w * pyr
200
  used.append(label.split(" [")[0])
 
 
 
 
201
 
202
  # Tier masses = perceived intensity over dry-down
203
  tier_mass = tier_blend.sum(axis=1) # (3,)
 
175
  return pyr
176
 
177
 
178
+ def _row_pair(r):
179
+ """Extract (label, conc) from a Dataframe row regardless of shape.
180
+
181
+ Gradio 6 may deliver rows as lists, tuples, numpy arrays, or dicts keyed by
182
+ header name. Normalise to (str label, float conc); return ("", 0.0) on junk.
183
+ """
184
+ try:
185
+ if isinstance(r, dict):
186
+ vals = list(r.values())
187
+ label = vals[0] if vals else ""
188
+ conc = vals[1] if len(vals) > 1 else 0
189
+ else:
190
+ label = r[0]
191
+ conc = r[1] if len(r) > 1 else 0
192
+ label = "" if label is None else str(label)
193
+ if hasattr(conc, "item"): # numpy scalar
194
+ conc = conc.item()
195
+ conc = float(conc) if conc not in (None, "") else 0.0
196
+ return label, conc
197
+ except (TypeError, ValueError, IndexError):
198
+ return "", 0.0
199
+
200
+
201
  def predict(arm_label, rows, progress=gr.Progress()):
202
+ pairs = [_row_pair(r) for r in (rows or [])]
203
+ pairs = [(l, c) for l, c in pairs if l and c > 0]
204
+ if not pairs:
205
+ return None, "Add at least one ingredient (with a concentration > 0)."
206
  try:
207
  model, heads, engine, resolved, objective_dim = _load_arm(arm_label)
208
  except Exception as e:
209
  return None, f"Model load failed: {e}"
210
 
211
  mats = {label: (sm, cas) for label, sm, cas in _materials()}
212
+ total_w = sum(c for _, c in pairs) or 1.0
213
  blend = np.zeros(objective_dim, dtype=np.float64) # (objective_dim,) tier-summed
214
  tier_blend = np.zeros((3, objective_dim), dtype=np.float64)
215
  used = []
216
+ skipped = []
217
+ for label, conc in progress.tqdm(pairs, desc="Encoding"):
218
+ if label not in mats:
219
+ skipped.append(label.split(" [")[0])
220
  continue
221
  sm, cas = mats[label]
222
  pyr = _pyramid_for_ingredient(model, heads, engine, sm, cas, objective_dim) # (3, D)
223
  w = conc / total_w
224
  tier_blend += w * pyr
225
  used.append(label.split(" [")[0])
226
+ if not used:
227
+ return None, ("None of the selected ingredients matched the catalog. "
228
+ "Pick ingredients from the Quick-add list." +
229
+ (f" Unmatched: {', '.join(skipped[:5])}" if skipped else ""))
230
 
231
  # Tier masses = perceived intensity over dry-down
232
  tier_mass = tier_blend.sum(axis=1) # (3,)