mshuaibi commited on
Commit
18668e8
·
1 Parent(s): cc22575

add overview + more info

Browse files
Files changed (2) hide show
  1. app.py +158 -21
  2. content.py +7 -5
app.py CHANGED
@@ -171,7 +171,11 @@ class LeaderboardData:
171
  """
172
  local_df = eval_results[split]
173
  local_df = local_df.map(
174
- lambda row: {"Model": model_hyperlink(row["url"], row["Model"])}
 
 
 
 
175
  )
176
  filtered_columns = (
177
  PRE_COLUMN_NAMES
@@ -195,8 +199,9 @@ class LeaderboardData:
195
  df[f"{subsplit}_forces_mae"] = df[f"{subsplit}_forces_mae"]
196
  df = df.rename(
197
  columns={
198
- f"{subsplit}_energy_mae": "Energy MAE [meV]",
199
- f"{subsplit}_forces_mae": "Forces MAE [meV/Å]",
 
200
  }
201
  )
202
  return df
@@ -207,7 +212,11 @@ class LeaderboardData:
207
  """
208
  local_df = eval_results[split]
209
  local_df = local_df.map(
210
- lambda row: {"Model": model_hyperlink(row["url"], row["Model"])}
 
 
 
 
211
  )
212
  eval_columns = LEADERBOARD_COLUMNS[split]
213
  filtered_columns = PRE_COLUMN_NAMES + eval_columns + POST_COLUMN_NAMES
@@ -242,18 +251,19 @@ LEADERBOARD_COLUMNS = {
242
  }
243
 
244
  COLUMN_MAPPING = {
245
- "interaction_energy_mae": "Ixn Energy MAE [meV]",
246
- "interaction_forces_mae": "Ixn Forces MAE [meV/Å]",
247
- "strain_energy_mae": "Strain Energy MAE [meV]",
248
- "deltaE_mae": "\u0394Energy MAE [meV]",
249
- "deltaF_mae": "\u0394Forces MAE [meV/Å]",
250
  "ensemble_rmsd": "RMSD [Å]",
251
  "global_min_rmsd": "RMSD [Å]",
252
  "rmsd": "RMSD [Å]",
253
- "lr_ddE_mae": "\u0394Energy (LR) MAE [meV]",
254
- "lr_ddF_mae": "\u0394Forces (LR) MAE [meV/Å]",
255
- "sr_ddE_mae": "\u0394Energy (SR) MAE [meV]",
256
- "sr_ddF_mae": "\u0394Forces (SR) MAE [meV/Å]",
 
257
  }
258
 
259
 
@@ -262,7 +272,9 @@ def add_new_eval(
262
  eval_type: str,
263
  organization: str,
264
  model: str,
265
- url: str,
 
 
266
  mail: str,
267
  training_set: str,
268
  additional_info: str,
@@ -331,8 +343,10 @@ def add_new_eval(
331
  "Organization": organization,
332
  "Submission date": submission_time,
333
  "Training Set": training_set,
 
 
 
334
  "Notes": additional_info,
335
- "url": url,
336
  }
337
  eval_entry.update(metrics)
338
 
@@ -388,7 +402,10 @@ def add_new_eval(
388
 
389
 
390
  def create_dataframe_tab(
391
- tab_name: str, df: pd.DataFrame, datatype: List[str] = None
 
 
 
392
  ) -> gr.Tab:
393
  """
394
  Create a tab with a dataframe.
@@ -396,12 +413,19 @@ def create_dataframe_tab(
396
  if datatype is None:
397
  datatype = TYPES
398
 
 
 
 
 
 
 
399
  with gr.Tab(tab_name) as tab:
400
  gr.Dataframe(
401
  value=df,
402
  datatype=datatype,
403
  interactive=False,
404
- column_widths=["20%"],
 
405
  )
406
  return tab
407
 
@@ -425,15 +449,121 @@ def create_s2ef_tabs(split: str, results_dfs: Dict[str, pd.DataFrame]) -> None:
425
 
426
  def create_evaluation_tabs(results_dfs: Dict[str, pd.DataFrame]) -> None:
427
  """
428
- Create evaluation tabs for non-S2EF evaluations.
429
  """
430
  eval_datatype = ["markdown", "markdown", "number", "str"]
431
 
 
 
 
 
 
432
  for eval_type in OTHER_EVAL_TYPES:
433
  display_name = "IE/EA" if eval_type == "IE_EA" else eval_type
434
  create_dataframe_tab(display_name, results_dfs[eval_type], eval_datatype)
435
 
436
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
  def create_submission_interface() -> Tuple[gr.components.Component, ...]:
438
  """
439
  Create the submission interface components.
@@ -444,7 +574,11 @@ def create_submission_interface() -> Tuple[gr.components.Component, ...]:
444
  with gr.Row():
445
  with gr.Column():
446
  model_name_textbox = gr.Textbox(label="Model name")
447
- model_url = gr.Textbox(label="Model/Paper URL")
 
 
 
 
448
  dataset = gr.Dropdown(
449
  choices=["OMol-All", "OMol-4M", "UMA-459M", "Other"],
450
  label="Training set",
@@ -478,6 +612,8 @@ def create_submission_interface() -> Tuple[gr.components.Component, ...]:
478
  organization,
479
  model_name_textbox,
480
  model_url,
 
 
481
  mail,
482
  dataset,
483
  additional_info,
@@ -523,6 +659,8 @@ def create_interface() -> gr.Blocks:
523
  organization,
524
  model_name_textbox,
525
  model_url,
 
 
526
  mail,
527
  dataset,
528
  additional_info,
@@ -531,7 +669,7 @@ def create_interface() -> gr.Blocks:
531
 
532
  submit_button.click(
533
  lambda x: "Coming soon :)",
534
- None,
535
  submission_result,
536
  # add_new_eval,
537
  # [
@@ -545,7 +683,6 @@ def create_interface() -> gr.Blocks:
545
  # additional_info,
546
  # ],
547
  # submission_result,
548
-
549
  )
550
 
551
  return demo
 
171
  """
172
  local_df = eval_results[split]
173
  local_df = local_df.map(
174
+ lambda row: {
175
+ "Model": model_hyperlink(
176
+ row["model_url"], row["paper_url"], row["Model"]
177
+ )
178
+ }
179
  )
180
  filtered_columns = (
181
  PRE_COLUMN_NAMES
 
199
  df[f"{subsplit}_forces_mae"] = df[f"{subsplit}_forces_mae"]
200
  df = df.rename(
201
  columns={
202
+ f"{subsplit}_energy_mae": "Energy MAE\n[meV]",
203
+ f"{subsplit}_forces_mae": "Forces MAE\n[meV/Å]",
204
+ "Energy Conserving": "Energy\nConserving",
205
  }
206
  )
207
  return df
 
212
  """
213
  local_df = eval_results[split]
214
  local_df = local_df.map(
215
+ lambda row: {
216
+ "Model": model_hyperlink(
217
+ row["model_url"], row["paper_url"], row["Model"]
218
+ )
219
+ }
220
  )
221
  eval_columns = LEADERBOARD_COLUMNS[split]
222
  filtered_columns = PRE_COLUMN_NAMES + eval_columns + POST_COLUMN_NAMES
 
251
  }
252
 
253
  COLUMN_MAPPING = {
254
+ "interaction_energy_mae": "Ixn Energy\nMAE [meV]",
255
+ "interaction_forces_mae": "Ixn Forces\nMAE [meV/Å]",
256
+ "strain_energy_mae": "Strain Energy\nMAE [meV]",
257
+ "deltaE_mae": "\u0394Energy MAE\n[meV]",
258
+ "deltaF_mae": "\u0394Forces MAE\n[meV/Å]",
259
  "ensemble_rmsd": "RMSD [Å]",
260
  "global_min_rmsd": "RMSD [Å]",
261
  "rmsd": "RMSD [Å]",
262
+ "lr_ddE_mae": "\u0394Energy (LR)\n MAE [meV]",
263
+ "lr_ddF_mae": "\u0394Forces (LR)\n MAE [meV/Å]",
264
+ "sr_ddE_mae": "\u0394Energy (SR)\n MAE [meV]",
265
+ "sr_ddF_mae": "\u0394Forces (SR)\n MAE [meV/Å]",
266
+ "Energy Conserving": "Energy\nConserving",
267
  }
268
 
269
 
 
272
  eval_type: str,
273
  organization: str,
274
  model: str,
275
+ model_url: str,
276
+ paper_url: str,
277
+ energy_conserving: bool,
278
  mail: str,
279
  training_set: str,
280
  additional_info: str,
 
343
  "Organization": organization,
344
  "Submission date": submission_time,
345
  "Training Set": training_set,
346
+ "Energy Conserving": "✅" if energy_conserving else "",
347
+ "model_url": model_url,
348
+ "paper_url": paper_url,
349
  "Notes": additional_info,
 
350
  }
351
  eval_entry.update(metrics)
352
 
 
402
 
403
 
404
  def create_dataframe_tab(
405
+ tab_name: str,
406
+ df: pd.DataFrame,
407
+ datatype: List[str] = None,
408
+ widths: List[str] = None,
409
  ) -> gr.Tab:
410
  """
411
  Create a tab with a dataframe.
 
413
  if datatype is None:
414
  datatype = TYPES
415
 
416
+ if widths is None:
417
+ num_cols = len(df.columns)
418
+ fixed_cols = len(PRE_COLUMN_NAMES) + len(POST_COLUMN_NAMES)
419
+ # Model | Organization |Energy Conserving | Training Set | Metrics | date
420
+ widths = ["10%", "5%", "5%", "5%"] + ["5%"] * (num_cols - fixed_cols) + ["10%"]
421
+
422
  with gr.Tab(tab_name) as tab:
423
  gr.Dataframe(
424
  value=df,
425
  datatype=datatype,
426
  interactive=False,
427
+ show_search="filter",
428
+ column_widths=widths,
429
  )
430
  return tab
431
 
 
449
 
450
  def create_evaluation_tabs(results_dfs: Dict[str, pd.DataFrame]) -> None:
451
  """
452
+ Create evaluation tabs for non-S2EF evaluations, including Overview tab.
453
  """
454
  eval_datatype = ["markdown", "markdown", "number", "str"]
455
 
456
+ # Create Overview tab first
457
+ overview_df = create_overview_dataframe(results_dfs)
458
+ create_dataframe_tab("Overview", overview_df, eval_datatype, widths=["10%"])
459
+
460
+ # Create individual evaluation tabs
461
  for eval_type in OTHER_EVAL_TYPES:
462
  display_name = "IE/EA" if eval_type == "IE_EA" else eval_type
463
  create_dataframe_tab(display_name, results_dfs[eval_type], eval_datatype)
464
 
465
 
466
+ def create_overview_dataframe(results_dfs: Dict[str, pd.DataFrame]) -> pd.DataFrame:
467
+ """
468
+ Create an overview dataframe combining all models with only the first metric from each eval type.
469
+ """
470
+ # Initialize overview data with model info
471
+ overview_data = {}
472
+
473
+ # Get all unique model-dataset combinations across all dataframes
474
+ all_model_entries = set()
475
+ model_info = {} # Store model metadata (org, dataset, etc.)
476
+
477
+ # Collect all models and their info from all evaluation types
478
+ for eval_type, df in results_dfs.items():
479
+ if eval_type.startswith("Validation_") or eval_type.startswith("Test_"):
480
+ continue
481
+
482
+ for _, row in df.iterrows():
483
+ model_name = row["Model"]
484
+ dataset = row["Training Set"]
485
+ # Create unique identifier combining model name and training set
486
+ model_entry = (model_name, dataset)
487
+ all_model_entries.add(model_entry)
488
+ # Store model metadata for this specific entry
489
+ model_info[model_entry] = {
490
+ "Model": model_name,
491
+ "Organization": row.get("Organization", ""),
492
+ "Energy Conserving": row.get("Energy\nConserving", ""),
493
+ "Training Set": dataset,
494
+ }
495
+
496
+ # Initialize overview data structure
497
+ overview_data = {
498
+ "Model": [],
499
+ "Organization": [],
500
+ "Energy Conserving": [],
501
+ "Training Set": [],
502
+ }
503
+
504
+ # Add columns for the primary metric from each evaluation type
505
+ metric_columns = {}
506
+
507
+ # Add primary metric from each OTHER evaluation type (skip S2EF)
508
+ for eval_type in OTHER_EVAL_TYPES:
509
+ if eval_type in results_dfs and eval_type in LEADERBOARD_COLUMNS:
510
+ primary_metric = LEADERBOARD_COLUMNS[eval_type][0] # First metric
511
+ # Map to display name using COLUMN_MAPPING
512
+ metric_display_name = COLUMN_MAPPING.get(primary_metric, primary_metric)
513
+ # Include task name to avoid conflicts when multiple tasks have same metric
514
+ task_display_name = "IE/EA" if eval_type == "IE_EA" else eval_type
515
+ full_display_name = f"{task_display_name}\n{metric_display_name}"
516
+ overview_data[full_display_name] = []
517
+ metric_columns[full_display_name] = (eval_type, metric_display_name)
518
+
519
+ # Populate data for each model entry
520
+ for model_entry in sorted(
521
+ all_model_entries, key=lambda x: (x[0], x[1])
522
+ ): # Sort by model name, then dataset
523
+ model_name, dataset = model_entry
524
+ entry_info = model_info[model_entry]
525
+
526
+ overview_data["Model"].append(entry_info["Model"])
527
+ overview_data["Organization"].append(entry_info["Organization"])
528
+ overview_data["Energy Conserving"].append(entry_info["Energy Conserving"])
529
+ overview_data["Training Set"].append(entry_info["Training Set"])
530
+
531
+ # Fill in metrics for each column
532
+ for display_col, (eval_type, source_col) in metric_columns.items():
533
+ if eval_type in results_dfs:
534
+ df = results_dfs[eval_type]
535
+ # Match both model name and training set
536
+ model_row = df[
537
+ (df["Model"] == model_name) & (df["Training Set"] == dataset)
538
+ ]
539
+ if not model_row.empty and source_col in model_row.columns:
540
+ value = model_row.iloc[0][source_col]
541
+ else:
542
+ value = "-"
543
+ else:
544
+ value = "-"
545
+ overview_data[display_col].append(value)
546
+
547
+ overview_df = pd.DataFrame(overview_data)
548
+
549
+ # Sort by the average of all metric columns (ascending for MAE metrics)
550
+ metric_cols = [
551
+ col
552
+ for col in overview_df.columns
553
+ if col not in PRE_COLUMN_NAMES + POST_COLUMN_NAMES
554
+ ]
555
+ if metric_cols:
556
+ # Calculate average across all metric columns for each row
557
+ # Convert all metric columns to numeric, keeping "-" as NaN
558
+ numeric_metrics = overview_df[metric_cols].apply(pd.to_numeric, errors="coerce")
559
+ # Calculate mean across columns, ignoring NaN values
560
+ avg_scores = numeric_metrics.mean(axis=1)
561
+ # Sort by average score (ascending for MAE metrics)
562
+ overview_df = overview_df.loc[avg_scores.sort_values(na_position="last").index]
563
+
564
+ return overview_df
565
+
566
+
567
  def create_submission_interface() -> Tuple[gr.components.Component, ...]:
568
  """
569
  Create the submission interface components.
 
574
  with gr.Row():
575
  with gr.Column():
576
  model_name_textbox = gr.Textbox(label="Model name")
577
+ energy_conserving = gr.Checkbox(
578
+ label="Is the model energy conserving? (i.e. F= -dE/dx)"
579
+ )
580
+ model_url = gr.Textbox(label="Model/Checkpoint URL")
581
+ paper_url = gr.Textbox(label="Paper URL")
582
  dataset = gr.Dropdown(
583
  choices=["OMol-All", "OMol-4M", "UMA-459M", "Other"],
584
  label="Training set",
 
612
  organization,
613
  model_name_textbox,
614
  model_url,
615
+ paper_url,
616
+ energy_conserving,
617
  mail,
618
  dataset,
619
  additional_info,
 
659
  organization,
660
  model_name_textbox,
661
  model_url,
662
+ paper_url,
663
+ energy_conserving,
664
  mail,
665
  dataset,
666
  additional_info,
 
669
 
670
  submit_button.click(
671
  lambda x: "Coming soon :)",
672
+ [0],
673
  submission_result,
674
  # add_new_eval,
675
  # [
 
683
  # additional_info,
684
  # ],
685
  # submission_result,
 
686
  )
687
 
688
  return demo
content.py CHANGED
@@ -60,13 +60,15 @@ CITATION_BUTTON_TEXT = r"""
60
  """
61
 
62
  # Table configuration
63
- PRE_COLUMN_NAMES = ["Model", "Organization", "Training Set"]
64
  POST_COLUMN_NAMES = ["Submission date"]
65
- TYPES = ["markdown", "markdown", "str", "number", "number", "str"]
66
 
67
 
68
- def model_hyperlink(link: str, model_name: str) -> str:
69
  """Create a hyperlink for model names in the leaderboard."""
70
- if not link or link.strip() == "":
71
  return model_name
72
- return f'<a target="_blank" href="{link}" style="color: var(--link-text-color); text-decoration: underline;text-decoration-style: dotted;">{model_name}</a>'
 
 
 
60
  """
61
 
62
  # Table configuration
63
+ PRE_COLUMN_NAMES = ["Model", "Organization", "Energy Conserving", "Training Set"]
64
  POST_COLUMN_NAMES = ["Submission date"]
65
+ TYPES = ["markdown", "str", "bool", "str"]
66
 
67
 
68
+ def model_hyperlink(model_link: str, paper_link: str, model_name: str) -> str:
69
  """Create a hyperlink for model names in the leaderboard."""
70
+ if not model_link or model_link.strip() == "":
71
  return model_name
72
+ if not paper_link or paper_link.strip() == "" or paper_link == "-":
73
+ return f'<a target="_blank" href="{model_link}" style="color: var(--link-text-color); text-decoration: underline;text-decoration-style: dotted;" title="Download model">{model_name}</a>'
74
+ return f'<a target="_blank" href="{model_link}" style="color: var(--link-text-color); text-decoration: underline;text-decoration-style: dotted;" title="Download model">{model_name}</a> <a target="_blank" href="{paper_link}" style="color: var(--link-text-color); text-decoration: underline;text-decoration-style: dotted;" title="Read paper">📕</a>'