duongthienz commited on
Commit
0e1bd85
·
verified ·
1 Parent(s): cb4f3c7

Add a new cross file chart

Browse files
Files changed (1) hide show
  1. utils.py +57 -0
utils.py CHANGED
@@ -538,6 +538,63 @@ def build_multifile_category_df(validNames, results, summaries, categories, cate
538
  return pd.DataFrame(df6_dict), allCategories
539
 
540
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
  def build_multifile_voice_df(validNames, summaries):
542
  """Build df7 (no/one/multi voice percentages per file) for the multi-file expander."""
543
  voiceNames = ["No Voice", "Single Voice", "Multi Voice"]
 
538
  return pd.DataFrame(df6_dict), allCategories
539
 
540
 
541
+ def build_multifile_role_voice_df(validNames, results, summaries, categories,
542
+ categorySelect, speakerRenames=None):
543
+ """Build df8: per-file proportions split by role for single voice, plus
544
+ Multi Voice and No Voice.
545
+
546
+ Single Voice time is broken down into each role and an Unassigned bucket
547
+ (speakers in single-voice segments that haven't been assigned to any role).
548
+ Multi Voice and No Voice come from df5 percentiles (0-100 scale) converted
549
+ to 0-1 proportions.
550
+
551
+ This is the combination of df6 (role proportions) and df7 (voice categories)
552
+ where Single Voice is replaced by its constituent roles.
553
+ """
554
+ speakerRenames = speakerRenames or {}
555
+ col_names = list(categories) + ["Unassigned", "Multi Voice", "No Voice"]
556
+ df8_dict = {"files": validNames}
557
+ for col in col_names:
558
+ df8_dict[col] = []
559
+
560
+ for fn in validNames:
561
+ currAnnotation, totalSeconds = results[fn]
562
+ safe_total = max(totalSeconds, 1)
563
+ prefix = fn + ": "
564
+ renames = speakerRenames.get(fn, {})
565
+
566
+ # Role proportions — same logic as build_multifile_category_df
567
+ assigned_all = set()
568
+ for i, category in enumerate(categories):
569
+ assigned_sps = [
570
+ t[len(prefix):]
571
+ for t in (categorySelect[i] if i < len(categorySelect) else [])
572
+ if t.startswith(prefix)
573
+ ]
574
+ valid_sps = [sp for sp in assigned_sps if sp in currAnnotation.labels()]
575
+ assigned_all.update(valid_sps)
576
+ if valid_sps:
577
+ val = su.sumTimes(currAnnotation.subset(valid_sps)) / safe_total
578
+ else:
579
+ val = 0.0
580
+ df8_dict[category].append(min(val, 1.0))
581
+
582
+ # Unassigned speakers
583
+ unassigned_sps = [sp for sp in currAnnotation.labels() if sp not in assigned_all]
584
+ if unassigned_sps:
585
+ val = su.sumTimes(currAnnotation.subset(unassigned_sps)) / safe_total
586
+ else:
587
+ val = 0.0
588
+ df8_dict["Unassigned"].append(min(val, 1.0))
589
+
590
+ # Multi Voice and No Voice from df5 percentiles (0-100 → 0-1)
591
+ partial = summaries[fn]["df5"]
592
+ df8_dict["No Voice"].append(partial["percentiles"][0] / 100)
593
+ df8_dict["Multi Voice"].append(partial["percentiles"][2] / 100)
594
+
595
+ return pd.DataFrame(df8_dict), col_names
596
+
597
+
598
  def build_multifile_voice_df(validNames, summaries):
599
  """Build df7 (no/one/multi voice percentages per file) for the multi-file expander."""
600
  voiceNames = ["No Voice", "Single Voice", "Multi Voice"]