duongthienz commited on
Commit
aa72991
·
verified ·
1 Parent(s): 294a6f2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +206 -312
app.py CHANGED
@@ -20,6 +20,7 @@ import torch
20
  #import torch_xla.core.xla_model as xm
21
  from pyannote.audio import Pipeline
22
  from pyannote.core import Annotation, Segment, Timeline
 
23
  import datetime as dt
24
 
25
  enableDenoise = False
@@ -38,22 +39,7 @@ def printV(message,verbosityLevel):
38
  global verbosity
39
  if verbosity>=verbosityLevel:
40
  print(message)
41
-
42
- def get_display_name(speaker, fileIndex):
43
- """Return the user-assigned display name for a speaker, or the original label."""
44
- renames = st.session_state.speakerRenames
45
- if fileIndex < len(renames) and speaker in renames[fileIndex]:
46
- return renames[fileIndex][speaker]
47
- return speaker
48
 
49
- def apply_speaker_renames_to_df(df, fileIndex, column="task"):
50
- """Replace speaker_## labels in a DataFrame column with display names."""
51
- if column not in df.columns:
52
- return df
53
- df = df.copy()
54
- df[column] = df[column].apply(lambda s: get_display_name(s, fileIndex))
55
- return df
56
-
57
  @st.cache_data
58
  def convert_df(df):
59
  return df.to_csv(index=False).encode('utf-8')
@@ -158,7 +144,7 @@ def updateCategoryOptions(resultIndex):
158
  #st.info(f"After update: {st.session_state.categorySelect}")
159
 
160
  def updateMultiSelect():
161
- currFileIndex = st.session_state.file_names.index(st.session_state["select_currFile"])
162
  st.session_state.resetResult = True
163
  for i, category in enumerate(st.session_state['categories']):
164
  st.session_state[f'multiselect_{category}'] = st.session_state['categorySelect'][currFileIndex][i]
@@ -198,113 +184,92 @@ def analyze(inFileName):
198
  st.session_state.summaries[currFileIndex]["df3"] = df3
199
  printV(f'Set df3',4)
200
 
201
- # --- Build df4 ---
202
  nameList = st.session_state.categories
203
  extraNames = []
204
  valueList = [0 for i in range(len(nameList))]
205
  extraValues = []
206
-
207
  for sp in speakerNames:
208
  foundSp = False
209
  for i, categoryName in enumerate(nameList):
210
  if sp in categorySelections[i]:
 
211
  valueList[i] += su.sumTimes(currAnnotation.subset([sp]))
212
  foundSp = True
213
  break
214
- if not foundSp:
 
 
215
  extraNames.append(sp)
216
  extraValues.append(su.sumTimes(currAnnotation.subset([sp])))
217
-
218
- if extraNames:
219
- extraPairsSorted = sorted(zip(extraNames, extraValues), key=lambda pair: pair[0])
220
- extraNames, extraValues = list(zip(*extraPairsSorted))
221
- extraNames = list(extraNames)
222
- extraValues = list(extraValues)
223
- else:
224
- extraNames, extraValues = [], []
225
-
226
  df4_dict = {
227
- "values": valueList + extraValues,
228
- "names": nameList + extraNames,
229
- }
230
  df4 = pd.DataFrame(data=df4_dict)
231
  df4.name = "df4"
232
  st.session_state.summaries[currFileIndex]["df4"] = df4
233
- printV(f'Set df4', 4)
234
 
235
- # --- Build df5 ---
236
- speakerList, timeList = su.sumTimesPerSpeaker(oneVoice)
 
237
  multiSpeakerList, multiTimeList = su.sumMultiTimesPerSpeaker(multiVoice)
238
-
239
- speakerList = list(speakerList) if speakerList else []
240
- timeList = list(timeList) if timeList else []
241
- multiSpeakerList = list(multiSpeakerList) if multiSpeakerList else []
242
- multiTimeList = list(multiTimeList) if multiTimeList else []
243
-
244
- summativeMultiSpeaker = sum(multiTimeList) if multiTimeList else 1
245
- safeOneVoice = sumOneVoice if sumOneVoice > 0 else 1
246
-
247
- basePercentiles = [
248
- sumNoVoice / currTotalTime,
249
- sumOneVoice / currTotalTime,
250
- sumMultiVoice / currTotalTime,
251
- ]
252
-
253
- timeStrings = su.timeToString(timeList) if timeList else []
254
- multiTimeStrings = su.timeToString(multiTimeList) if multiTimeList else []
255
- if isinstance(timeStrings, str):
256
- timeStrings = [timeStrings]
257
- if isinstance(multiTimeStrings, str):
258
- multiTimeStrings = [multiTimeStrings]
259
-
260
- n_ov = len(speakerList)
261
- n_mv = len(multiSpeakerList)
262
-
263
- df5 = pd.DataFrame({
264
- "ids": ["NV", "OV", "MV"] + [f"OV_{i}" for i in range(n_ov)] + [f"MV_{i}" for i in range(n_mv)],
265
- "labels": ["No Voice", "One Voice", "Multi Voice"] + speakerList + multiSpeakerList,
266
- "parents": ["", "", ""] + ["OV"] * n_ov + ["MV"] * n_mv,
267
- "parentNames": ["Total", "Total", "Total"] + ["One Voice"] * n_ov + ["Multi Voice"] * n_mv,
268
- "values": [sumNoVoice, sumOneVoice, sumMultiVoice] + timeList + multiTimeList,
269
- "valueStrings": [
270
- su.timeToString(sumNoVoice),
271
- su.timeToString(sumOneVoice),
272
- su.timeToString(sumMultiVoice),
273
- ] + timeStrings + multiTimeStrings,
274
- "percentiles": [
275
- basePercentiles[0] * 100,
276
- basePercentiles[1] * 100,
277
- basePercentiles[2] * 100,
278
- ] + [(t * 100) / safeOneVoice * basePercentiles[1] for t in timeList]
279
- + [(t * 100) / summativeMultiSpeaker * basePercentiles[2] for t in multiTimeList],
280
- "parentPercentiles": [
281
- basePercentiles[0] * 100,
282
- basePercentiles[1] * 100,
283
- basePercentiles[2] * 100,
284
- ] + [(t * 100) / safeOneVoice for t in timeList]
285
- + [(t * 100) / summativeMultiSpeaker for t in multiTimeList],
286
- })
287
  df5.name = "df5"
288
  st.session_state.summaries[currFileIndex]["df5"] = df5
289
- printV(f'Set df5', 4)
290
-
291
- # --- Build speakers_dataFrame, df2 ---
292
- speakers_dataFrame, speakers_times = su.annotationToDataFrame(currAnnotation)
293
  st.session_state.summaries[currFileIndex]["speakers_dataFrame"] = speakers_dataFrame
294
  st.session_state.summaries[currFileIndex]["speakers_times"] = speakers_times
295
 
296
  df2_dict = {
297
- "values": [100 * t / currTotalTime for t in df4_dict["values"]],
298
- "names": df4_dict["names"],
299
  }
300
  df2 = pd.DataFrame(df2_dict)
301
  st.session_state.summaries[currFileIndex]["df2"] = df2
302
- printV(f'Set df2', 4)
303
- except Exception as e:
304
- import traceback
305
- print(f"Error in analyze: {e}")
306
- traceback.print_exc()
307
- st.error(f"Debug - analyze() failed: {e}")
308
 
309
  #----------------------------------------------------------------------------------------------------------------------
310
 
@@ -350,8 +315,6 @@ pipeline.to(device)#torch.device("cuda"))
350
  # Long-range usage
351
  if 'results' not in st.session_state:
352
  st.session_state.results = []
353
- if 'speakerRenames' not in st.session_state:
354
- st.session_state.speakerRenames = []
355
  if 'summaries' not in st.session_state:
356
  st.session_state.summaries = []
357
  if 'categories' not in st.session_state:
@@ -425,14 +388,10 @@ if uploaded_file_paths is not None:
425
  st.session_state.categorySelect.append(tempCategories)
426
  while (len(st.session_state.summaries) < len(valid_files)):
427
  st.session_state.summaries.append([])
428
- while (len(st.session_state.speakerRenames) < len(valid_files)):
429
- st.session_state.speakerRenames.append({})
430
 
431
  st.session_state.file_names = file_names
432
 
433
  file_names = st.session_state.file_names
434
- if not file_names:
435
- file_names = []
436
 
437
  if len(file_names) == 0:
438
  st.text("Upload file(s) to enable analysis")
@@ -535,8 +494,6 @@ if st.sidebar.button("Load Demo Example"):
535
  st.session_state.categorySelect.append(tempCategories)
536
  while (len(st.session_state.summaries) < len(valid_files)):
537
  st.session_state.summaries.append([])
538
- while (len(st.session_state.speakerRenames) < len(valid_files)):
539
- st.session_state.speakerRenames.append({})
540
 
541
  with st.spinner(text=f'Loading Demo Sample'):
542
  # RTTM load as filler
@@ -548,8 +505,6 @@ if st.sidebar.button("Load Demo Example"):
548
  totalSeconds = segment.end
549
  st.session_state.results = [(annotations, totalSeconds)]
550
  st.session_state.summaries = [{}]
551
- while len(st.session_state.speakerRenames) < 1:
552
- st.session_state.speakerRenames.append({})
553
  speakerNames = annotations.labels()
554
  st.session_state.unusedSpeakers = [speakerNames]
555
  with st.spinner(text=f'Analyzing Demo Data'):
@@ -568,8 +523,6 @@ if currFile is None and len(st.session_state.results) > 0 and len(st.session_sta
568
  st.write("Select a file to view from the sidebar")
569
  try:
570
  st.session_state.resetResult = False
571
- if currFile is None:
572
- st.stop()
573
  currFileIndex = file_names.index(currFile)
574
  currPlainName = currFile.split('.')[0]
575
  if len(st.session_state.results) > currFileIndex and len(st.session_state.summaries) > currFileIndex and len(st.session_state.results[currFileIndex]) > 0:
@@ -601,27 +554,6 @@ try:
601
 
602
  newCategory = st.sidebar.text_input('Add category', key='categoryInput',on_change=addCategory)
603
 
604
- st.sidebar.divider()
605
- st.sidebar.subheader("Rename Speakers")
606
- st.sidebar.caption("Replace SPEAKER_## labels with real names.")
607
- current_renames = st.session_state.speakerRenames[currFileIndex]
608
- with st.sidebar.form("rename_form"):
609
- temp_renames = {}
610
- for sp in speakerNames:
611
- current_label = current_renames.get(sp, "")
612
- temp_renames[sp] = st.text_input(
613
- f"{sp}",
614
- value=current_label,
615
- placeholder="e.g. John",
616
- )
617
- if st.form_submit_button("Apply Names"):
618
- for sp, new_name in temp_renames.items():
619
- if new_name.strip():
620
- st.session_state.speakerRenames[currFileIndex][sp] = new_name.strip()
621
- elif sp in st.session_state.speakerRenames[currFileIndex]:
622
- del st.session_state.speakerRenames[currFileIndex][sp]
623
- st.rerun()
624
-
625
  catTypeColors = su.colorsCSS(3)
626
  allColors = su.colorsCSS(len(speakerNames)+len(st.session_state.categories))
627
  speakerColors = allColors[:len(speakerNames)]
@@ -650,8 +582,7 @@ try:
650
  st.session_state.summaries[currFileIndex]["df4"] = df4
651
 
652
  with dataTab:
653
- displayDF = apply_speaker_renames_to_df(currDF, currFileIndex, column="Resource")
654
- csv = convert_df(displayDF)
655
 
656
  st.download_button(
657
  "Press to Download analysis data",
@@ -661,7 +592,7 @@ try:
661
  key='download-csv',
662
  on_click="ignore",
663
  )
664
- st.dataframe(displayDF)
665
  with pie1:
666
  printV("In Pie1",4)
667
  df3 = st.session_state.summaries[currFileIndex]["df3"]
@@ -675,52 +606,46 @@ try:
675
  printV("Pie1 Pretrace",4)
676
  fig1.add_trace(go.Pie(values=df3["values"],labels=df3["names"],sort=False))
677
  printV("Pie1 Posttrace",4)
678
- st.plotly_chart(fig1, use_container_width=True, config=config)
679
  col1_1, col1_2 = st.columns(2)
680
- try:
681
- fig1.write_image("ascn_pie1.pdf")
682
- fig1.write_image("ascn_pie1.svg")
683
- except Exception:
684
- pass
685
  printV("Pie1 files written",4)
686
  with col1_1:
687
- if os.path.exists('ascn_pie1.pdf'):
688
- printV("Pie1 in col1_1",4)
689
- with open('ascn_pie1.pdf','rb') as f:
690
- printV("Pie1 in file open",4)
691
- st.download_button(
692
- "Save As PDF",
693
- f,
694
- 'sonogram-voice-category-'+currPlainName+'.pdf',
695
- 'application/pdf',
696
- key='download-pdf1',
697
- on_click="ignore",
698
- )
699
- printV("Pie1 after col1_1",4)
700
  with col1_2:
701
- if os.path.exists('ascn_pie1.svg'):
702
- with open('ascn_pie1.svg','rb') as f:
703
- st.download_button(
704
- "Save As SVG",
705
- f,
706
- 'sonogram-voice-category-'+currPlainName+'.svg',
707
- 'image/svg+xml',
708
- key='download-svg1',
709
- on_click="ignore",
710
- )
711
- printV("Pie1 in col1_2",4)
712
  printV("Pie1 post plotly",4)
713
 
714
  with pie2:
715
- printV("In Pie2",4)
716
- df4 = st.session_state.summaries[currFileIndex]["df4"].copy()
717
 
718
  # Some speakers may be missing, so fix colors
719
  figColors = []
720
  for n in df4["names"]:
721
  if n in speakerNames:
722
  figColors.append(speakerColors[speakerNames.index(n)])
723
- df4["names"] = df4["names"].apply(lambda s: get_display_name(s, currFileIndex))
724
  fig2 = go.Figure()
725
  fig2.update_layout(
726
  title_text="Percentage of Speakers and Custom Categories",
@@ -728,43 +653,35 @@ try:
728
  plot_bgcolor='rgba(0, 0, 0, 0)',
729
  paper_bgcolor='rgba(0, 0, 0, 0)',
730
  )
731
- printV("Pie2 Pretrace",4)
732
  fig2.add_trace(go.Pie(values=df4["values"],labels=df4["names"],sort=False))
733
- printV("Pie2 Posttrace",4)
734
- st.plotly_chart(fig2, use_container_width=True, config=config)
735
  col2_1, col2_2 = st.columns(2)
736
- try:
737
- fig2.write_image("ascn_pie2.pdf")
738
- fig2.write_image("ascn_pie2.svg")
739
- except Exception:
740
- pass
741
  with col2_1:
742
- if os.path.exists('ascn_pie2.pdf'):
743
- with open('ascn_pie2.pdf','rb') as f:
744
- st.download_button(
745
- "Save As PDF",
746
- f,
747
- 'sonogram-speaker-percent-'+currPlainName+'.pdf',
748
- 'application/pdf',
749
- key='download-pdf2',
750
- on_click="ignore",
751
- )
752
  with col2_2:
753
- if os.path.exists('ascn_pie2.svg'):
754
- with open('ascn_pie2.svg','rb') as f:
755
- st.download_button(
756
- "Save As SVG",
757
- f,
758
- 'sonogram-speaker-percent-'+currPlainName+'.svg',
759
- 'image/svg+xml',
760
- key='download-svg2',
761
- on_click="ignore",
762
- )
763
 
764
  with sunburst1:
765
- df5 = st.session_state.summaries[currFileIndex]["df5"].copy()
766
- df5["labels"] = df5["labels"].apply(lambda s: get_display_name(s, currFileIndex))
767
- df5["parentNames"] = df5["parentNames"].apply(lambda s: get_display_name(s, currFileIndex))
768
  fig3_1 = px.sunburst(df5,
769
  branchvalues = 'total',
770
  names = "labels",
@@ -789,40 +706,34 @@ try:
789
  plot_bgcolor='rgba(0, 0, 0, 0)',
790
  paper_bgcolor='rgba(0, 0, 0, 0)',
791
  )
792
- st.plotly_chart(fig3_1, use_container_width=True, config=config)
793
  col3_1, col3_2 = st.columns(2)
794
- try:
795
- fig3_1.write_image("ascn_sunburst.pdf")
796
- fig3_1.write_image("ascn_sunburst.svg")
797
- except Exception:
798
- pass
799
  with col3_1:
800
- if os.path.exists('ascn_sunburst.pdf'):
801
- with open('ascn_sunburst.pdf','rb') as f:
802
- st.download_button(
803
- "Save As PDF",
804
- f,
805
- 'sonogram-speaker-categories-'+currPlainName+'.pdf',
806
- 'application/pdf',
807
- key='download-pdf3',
808
- on_click="ignore",
809
- )
810
  with col3_2:
811
- if os.path.exists('ascn_sunburst.svg'):
812
- with open('ascn_sunburst.svg','rb') as f:
813
- st.download_button(
814
- "Save As SVG",
815
- f,
816
- 'sonogram-speaker-categories-'+currPlainName+'.svg',
817
- 'image/svg+xml',
818
- key='download-svg3',
819
- on_click="ignore",
820
- )
821
 
822
  with treemap1:
823
- df5 = st.session_state.summaries[currFileIndex]["df5"].copy()
824
- df5["labels"] = df5["labels"].apply(lambda s: get_display_name(s, currFileIndex))
825
- df5["parentNames"] = df5["parentNames"].apply(lambda s: get_display_name(s, currFileIndex))
826
  fig3 = px.treemap(df5,
827
  branchvalues = "total",
828
  names = "labels",
@@ -847,43 +758,37 @@ try:
847
  plot_bgcolor='rgba(0, 0, 0, 0)',
848
  paper_bgcolor='rgba(0, 0, 0, 0)',
849
  )
850
- st.plotly_chart(fig3, use_container_width=True, config=config)
851
  col4_1, col4_2 = st.columns(2)
852
- try:
853
- fig3.write_image("ascn_treemap.pdf")
854
- fig3.write_image("ascn_treemap.svg")
855
- except Exception:
856
- pass
857
  with col4_1:
858
- if os.path.exists('ascn_treemap.pdf'):
859
- with open('ascn_treemap.pdf','rb') as f:
860
- st.download_button(
861
- "Save As PDF",
862
- f,
863
- 'sonogram-treemap-'+currPlainName+'.pdf',
864
- 'application/pdf',
865
- key='download-pdf4',
866
- on_click="ignore",
867
- )
868
  with col4_2:
869
- if os.path.exists('ascn_treemap.svg'):
870
- with open('ascn_treemap.svg','rb') as f:
871
- st.download_button(
872
- "Save As SVG",
873
- f,
874
- 'sonogram-treemap-'+currPlainName+'.svg',
875
- 'image/svg+xml',
876
- key='download-svg4',
877
- on_click="ignore",
878
- )
879
 
880
  # generate plotting window
881
 
882
 
883
  with timeline:
884
- timeline_df = speakers_dataFrame.copy()
885
- timeline_df["Resource"] = timeline_df["Resource"].apply(lambda s: get_display_name(s, currFileIndex))
886
- fig_la = px.timeline(timeline_df, x_start="Start", x_end="Finish", y="Resource", color="Resource",title="Timeline of Audio with Speakers",
887
  color_discrete_sequence=speakerColors)
888
  fig_la.update_yaxes(autorange="reversed")
889
 
@@ -909,39 +814,34 @@ try:
909
  legend={'traceorder':'reversed'},
910
  yaxis= {'showticklabels': False},
911
  )
912
- st.plotly_chart(fig_la, use_container_width=True, config=config)
913
  col5_1, col5_2 = st.columns(2)
914
- try:
915
- fig_la.write_image("ascn_timeline.pdf")
916
- fig_la.write_image("ascn_timeline.svg")
917
- except Exception:
918
- pass
919
  with col5_1:
920
- if os.path.exists('ascn_timeline.pdf'):
921
- with open('ascn_timeline.pdf','rb') as f:
922
- st.download_button(
923
- "Save As PDF",
924
- f,
925
- 'sonogram-timeline-'+currPlainName+'.pdf',
926
- 'application/pdf',
927
- key='download-pdf5',
928
- on_click="ignore",
929
- )
930
  with col5_2:
931
- if os.path.exists('ascn_timeline.svg'):
932
- with open('ascn_timeline.svg','rb') as f:
933
- st.download_button(
934
- "Save As SVG",
935
- f,
936
- 'sonogram-timeline-'+currPlainName+'.svg',
937
- 'image/svg+xml',
938
- key='download-svg5',
939
- on_click="ignore",
940
- )
941
 
942
  with bar1:
943
- df2 = st.session_state.summaries[currFileIndex]["df2"].copy()
944
- df2["names"] = df2["names"].apply(lambda s: get_display_name(s, currFileIndex))
945
  fig2_la = px.bar(df2, x="values", y="names", color="names", orientation='h',
946
  custom_data=["names","values"],title="Time Spoken by each Speaker",
947
  color_discrete_sequence=catColors+speakerColors)
@@ -962,40 +862,34 @@ try:
962
  'Percentage of Time: %{customdata[1]:.2f}%'
963
  ])
964
  )
965
- st.plotly_chart(fig2_la, use_container_width=True, config=config)
966
  col6_1, col6_2 = st.columns(2)
967
- try:
968
- fig2_la.write_image("ascn_bar.pdf")
969
- fig2_la.write_image("ascn_bar.svg")
970
- except Exception:
971
- pass
972
  with col6_1:
973
- if os.path.exists('ascn_bar.pdf'):
974
- with open('ascn_bar.pdf','rb') as f:
975
- st.download_button(
976
- "Save As PDF",
977
- f,
978
- 'sonogram-speaker-time-'+currPlainName+'.pdf',
979
- 'application/pdf',
980
- key='download-pdf6',
981
- on_click="ignore",
982
- )
983
  with col6_2:
984
- if os.path.exists('ascn_bar.svg'):
985
- with open('ascn_bar.svg','rb') as f:
986
- st.download_button(
987
- "Save As SVG",
988
- f,
989
- 'sonogram-speaker-time-'+currPlainName+'.svg',
990
- 'image/svg+xml',
991
- key='download-svg6',
992
- on_click="ignore",
993
- )
994
-
995
- except ValueError as e:
996
- import traceback
997
- st.error(f"Rendering error: {e}")
998
- traceback.print_exc()
999
 
1000
  if len(st.session_state.results) > 0:
1001
  with st.expander("Multi-file Summary Data"):
 
20
  #import torch_xla.core.xla_model as xm
21
  from pyannote.audio import Pipeline
22
  from pyannote.core import Annotation, Segment, Timeline
23
+ from df.enhance import enhance, init_df
24
  import datetime as dt
25
 
26
  enableDenoise = False
 
39
  global verbosity
40
  if verbosity>=verbosityLevel:
41
  print(message)
 
 
 
 
 
 
 
42
 
 
 
 
 
 
 
 
 
43
  @st.cache_data
44
  def convert_df(df):
45
  return df.to_csv(index=False).encode('utf-8')
 
144
  #st.info(f"After update: {st.session_state.categorySelect}")
145
 
146
  def updateMultiSelect():
147
+ currFileIndex = file_names.index(st.session_state["select_currFile"])
148
  st.session_state.resetResult = True
149
  for i, category in enumerate(st.session_state['categories']):
150
  st.session_state[f'multiselect_{category}'] = st.session_state['categorySelect'][currFileIndex][i]
 
184
  st.session_state.summaries[currFileIndex]["df3"] = df3
185
  printV(f'Set df3',4)
186
 
187
+ df4_dict = {}
188
  nameList = st.session_state.categories
189
  extraNames = []
190
  valueList = [0 for i in range(len(nameList))]
191
  extraValues = []
192
+
193
  for sp in speakerNames:
194
  foundSp = False
195
  for i, categoryName in enumerate(nameList):
196
  if sp in categorySelections[i]:
197
+ #st.info(categoryName)
198
  valueList[i] += su.sumTimes(currAnnotation.subset([sp]))
199
  foundSp = True
200
  break
201
+ if foundSp:
202
+ continue
203
+ else:
204
  extraNames.append(sp)
205
  extraValues.append(su.sumTimes(currAnnotation.subset([sp])))
206
+ extraPairsSorted = sorted(zip(extraNames, extraValues), key=lambda pair: pair[0])
207
+ extraNames, extraValues = zip(*extraPairsSorted)
 
 
 
 
 
 
 
208
  df4_dict = {
209
+ "values": valueList+list(extraValues),
210
+ "names": nameList+list(extraNames),
211
+ }
212
  df4 = pd.DataFrame(data=df4_dict)
213
  df4.name = "df4"
214
  st.session_state.summaries[currFileIndex]["df4"] = df4
 
215
 
216
+ printV(f'Set df4',4)
217
+
218
+ speakerList,timeList = su.sumTimesPerSpeaker(oneVoice)
219
  multiSpeakerList, multiTimeList = su.sumMultiTimesPerSpeaker(multiVoice)
220
+ summativeMultiSpeaker = sum(multiTimeList)
221
+ basePercentiles = [sumNoVoice/currTotalTime,
222
+ sumOneVoice/currTotalTime,
223
+ sumMultiVoice/currTotalTime
224
+ ]
225
+ df5 = pd.DataFrame(
226
+ {
227
+ "ids" : ["NV","OV","MV"]+[f"OV_{i}" for i in range(len(speakerList))]
228
+ +[f"MV_{i}" for i in range(len(multiSpeakerList))],
229
+ "labels" : ["No Voice","One Voice","Multi Voice"] + speakerList + multiSpeakerList,
230
+ "parents" : ["","",""]+["OV" for i in range(len(speakerList))]
231
+ +["MV" for i in range(len(multiSpeakerList))],
232
+ "parentNames" : ["Total","Total","Total"]+["One Voice" for i in range(len(speakerList))]
233
+ +["Multi Voice" for i in range(len(multiSpeakerList))],
234
+ "values" : [sumNoVoice,
235
+ sumOneVoice,
236
+ sumMultiVoice,
237
+ ] + timeList + multiTimeList,
238
+ "valueStrings" : [su.timeToString(sumNoVoice),
239
+ su.timeToString(sumOneVoice),
240
+ su.timeToString(sumMultiVoice),
241
+ ] + su.timeToString(timeList) + su.timeToString(multiTimeList),
242
+ "percentiles" : [basePercentiles[0]*100,
243
+ basePercentiles[1]*100,
244
+ basePercentiles[2]*100] +
245
+ [(t*100) / sumOneVoice * basePercentiles[1] for t in timeList] +
246
+ [(t*100) / summativeMultiSpeaker * basePercentiles[2] for t in multiTimeList],
247
+ "parentPercentiles" : [basePercentiles[0]*100,
248
+ basePercentiles[1]*100,
249
+ basePercentiles[2]*100] +
250
+ [(t*100) / sumOneVoice for t in timeList] +
251
+ [(t*100) / summativeMultiSpeaker for t in multiTimeList],
252
+
253
+ }
254
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  df5.name = "df5"
256
  st.session_state.summaries[currFileIndex]["df5"] = df5
257
+ printV(f'Set df5',4)
258
+
259
+ speakers_dataFrame,speakers_times = su.annotationToDataFrame(currAnnotation)
 
260
  st.session_state.summaries[currFileIndex]["speakers_dataFrame"] = speakers_dataFrame
261
  st.session_state.summaries[currFileIndex]["speakers_times"] = speakers_times
262
 
263
  df2_dict = {
264
+ "values":[100*t/currTotalTime for t in df4_dict["values"]],
265
+ "names":df4_dict["names"]
266
  }
267
  df2 = pd.DataFrame(df2_dict)
268
  st.session_state.summaries[currFileIndex]["df2"] = df2
269
+ printV(f'Set df2',4)
270
+ except ValueError as e:
271
+ print(f"Value Error: {e}")
272
+ pass
 
 
273
 
274
  #----------------------------------------------------------------------------------------------------------------------
275
 
 
315
  # Long-range usage
316
  if 'results' not in st.session_state:
317
  st.session_state.results = []
 
 
318
  if 'summaries' not in st.session_state:
319
  st.session_state.summaries = []
320
  if 'categories' not in st.session_state:
 
388
  st.session_state.categorySelect.append(tempCategories)
389
  while (len(st.session_state.summaries) < len(valid_files)):
390
  st.session_state.summaries.append([])
 
 
391
 
392
  st.session_state.file_names = file_names
393
 
394
  file_names = st.session_state.file_names
 
 
395
 
396
  if len(file_names) == 0:
397
  st.text("Upload file(s) to enable analysis")
 
494
  st.session_state.categorySelect.append(tempCategories)
495
  while (len(st.session_state.summaries) < len(valid_files)):
496
  st.session_state.summaries.append([])
 
 
497
 
498
  with st.spinner(text=f'Loading Demo Sample'):
499
  # RTTM load as filler
 
505
  totalSeconds = segment.end
506
  st.session_state.results = [(annotations, totalSeconds)]
507
  st.session_state.summaries = [{}]
 
 
508
  speakerNames = annotations.labels()
509
  st.session_state.unusedSpeakers = [speakerNames]
510
  with st.spinner(text=f'Analyzing Demo Data'):
 
523
  st.write("Select a file to view from the sidebar")
524
  try:
525
  st.session_state.resetResult = False
 
 
526
  currFileIndex = file_names.index(currFile)
527
  currPlainName = currFile.split('.')[0]
528
  if len(st.session_state.results) > currFileIndex and len(st.session_state.summaries) > currFileIndex and len(st.session_state.results[currFileIndex]) > 0:
 
554
 
555
  newCategory = st.sidebar.text_input('Add category', key='categoryInput',on_change=addCategory)
556
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
557
  catTypeColors = su.colorsCSS(3)
558
  allColors = su.colorsCSS(len(speakerNames)+len(st.session_state.categories))
559
  speakerColors = allColors[:len(speakerNames)]
 
582
  st.session_state.summaries[currFileIndex]["df4"] = df4
583
 
584
  with dataTab:
585
+ csv = convert_df(currDF)
 
586
 
587
  st.download_button(
588
  "Press to Download analysis data",
 
592
  key='download-csv',
593
  on_click="ignore",
594
  )
595
+ st.dataframe(currDF)
596
  with pie1:
597
  printV("In Pie1",4)
598
  df3 = st.session_state.summaries[currFileIndex]["df3"]
 
606
  printV("Pie1 Pretrace",4)
607
  fig1.add_trace(go.Pie(values=df3["values"],labels=df3["names"],sort=False))
608
  printV("Pie1 Posttrace",4)
609
+
610
  col1_1, col1_2 = st.columns(2)
611
+ fig1.write_image("ascn_pie1.pdf")
612
+ fig1.write_image("ascn_pie1.svg")
 
 
 
613
  printV("Pie1 files written",4)
614
  with col1_1:
615
+ printV("Pie1 in col1_1",4)
616
+ with open('ascn_pie1.pdf','rb') as f:
617
+ printV("Pie1 in file open",4)
618
+ st.download_button(
619
+ "Save As PDF",
620
+ f,
621
+ 'sonogram-voice-category-'+currPlainName+'.pdf',
622
+ 'application/pdf',
623
+ key='download-pdf1',
624
+ on_click="ignore",
625
+ )
626
+ printV("Pie1 after col1_1",4)
 
627
  with col1_2:
628
+ with open('ascn_pie1.svg','rb') as f:
629
+ st.download_button(
630
+ "Save As SVG",
631
+ f,
632
+ 'sonogram-voice-category-'+currPlainName+'.svg',
633
+ 'image/svg+xml',
634
+ key='download-svg1',
635
+ on_click="ignore",
636
+ )
637
+ printV("Pie1 in col1_2",4)
638
+ st.plotly_chart(fig1, use_container_width=True,config=config)
639
  printV("Pie1 post plotly",4)
640
 
641
  with pie2:
642
+ df4 = st.session_state.summaries[currFileIndex]["df4"]
 
643
 
644
  # Some speakers may be missing, so fix colors
645
  figColors = []
646
  for n in df4["names"]:
647
  if n in speakerNames:
648
  figColors.append(speakerColors[speakerNames.index(n)])
 
649
  fig2 = go.Figure()
650
  fig2.update_layout(
651
  title_text="Percentage of Speakers and Custom Categories",
 
653
  plot_bgcolor='rgba(0, 0, 0, 0)',
654
  paper_bgcolor='rgba(0, 0, 0, 0)',
655
  )
 
656
  fig2.add_trace(go.Pie(values=df4["values"],labels=df4["names"],sort=False))
657
+
 
658
  col2_1, col2_2 = st.columns(2)
659
+ fig2.write_image("ascn_pie2.pdf")
660
+ fig2.write_image("ascn_pie2.svg")
 
 
 
661
  with col2_1:
662
+ with open('ascn_pie2.pdf','rb') as f:
663
+ st.download_button(
664
+ "Save As PDF",
665
+ f,
666
+ 'sonogram-speaker-percent-'+currPlainName+'.pdf',
667
+ 'application/pdf',
668
+ key='download-pdf2',
669
+ on_click="ignore",
670
+ )
 
671
  with col2_2:
672
+ with open('ascn_pie2.svg','rb') as f:
673
+ st.download_button(
674
+ "Save As SVG",
675
+ f,
676
+ 'sonogram-speaker-percent-'+currPlainName+'.svg',
677
+ 'image/svg+xml',
678
+ key='download-svg2',
679
+ on_click="ignore",
680
+ )
681
+ st.plotly_chart(fig2, use_container_width=True,config=config)
682
 
683
  with sunburst1:
684
+ df5 = st.session_state.summaries[currFileIndex]["df5"]
 
 
685
  fig3_1 = px.sunburst(df5,
686
  branchvalues = 'total',
687
  names = "labels",
 
706
  plot_bgcolor='rgba(0, 0, 0, 0)',
707
  paper_bgcolor='rgba(0, 0, 0, 0)',
708
  )
709
+
710
  col3_1, col3_2 = st.columns(2)
711
+ fig3_1.write_image("ascn_sunburst.pdf")
712
+ fig3_1.write_image("ascn_sunburst.svg")
 
 
 
713
  with col3_1:
714
+ with open('ascn_sunburst.pdf','rb') as f:
715
+ st.download_button(
716
+ "Save As PDF",
717
+ f,
718
+ 'sonogram-speaker-categories-'+currPlainName+'.pdf',
719
+ 'application/pdf',
720
+ key='download-pdf3',
721
+ on_click="ignore",
722
+ )
 
723
  with col3_2:
724
+ with open('ascn_sunburst.svg','rb') as f:
725
+ st.download_button(
726
+ "Save As SVG",
727
+ f,
728
+ 'sonogram-speaker-categories-'+currPlainName+'.svg',
729
+ 'image/svg+xml',
730
+ key='download-svg3',
731
+ on_click="ignore",
732
+ )
733
+ st.plotly_chart(fig3_1, use_container_width=True,config=config)
734
 
735
  with treemap1:
736
+ df5 = st.session_state.summaries[currFileIndex]["df5"]
 
 
737
  fig3 = px.treemap(df5,
738
  branchvalues = "total",
739
  names = "labels",
 
758
  plot_bgcolor='rgba(0, 0, 0, 0)',
759
  paper_bgcolor='rgba(0, 0, 0, 0)',
760
  )
761
+
762
  col4_1, col4_2 = st.columns(2)
763
+ fig3.write_image("ascn_treemap.pdf")
764
+ fig3.write_image("ascn_treemap.svg")
 
 
 
765
  with col4_1:
766
+ with open('ascn_treemap.pdf','rb') as f:
767
+ st.download_button(
768
+ "Save As PDF",
769
+ f,
770
+ 'sonogram-treemap-'+currPlainName+'.pdf',
771
+ 'application/pdf',
772
+ key='download-pdf4',
773
+ on_click="ignore",
774
+ )
 
775
  with col4_2:
776
+ with open('ascn_treemap.svg','rb') as f:
777
+ st.download_button(
778
+ "Save As SVG",
779
+ f,
780
+ 'sonogram-treemap-'+currPlainName+'.svg',
781
+ 'image/svg+xml',
782
+ key='download-svg4',
783
+ on_click="ignore",
784
+ )
785
+ st.plotly_chart(fig3, use_container_width=True,config=config)
786
 
787
  # generate plotting window
788
 
789
 
790
  with timeline:
791
+ fig_la = px.timeline(speakers_dataFrame, x_start="Start", x_end="Finish", y="Resource", color="Resource",title="Timeline of Audio with Speakers",
 
 
792
  color_discrete_sequence=speakerColors)
793
  fig_la.update_yaxes(autorange="reversed")
794
 
 
814
  legend={'traceorder':'reversed'},
815
  yaxis= {'showticklabels': False},
816
  )
817
+
818
  col5_1, col5_2 = st.columns(2)
819
+ fig_la.write_image("ascn_timeline.pdf")
820
+ fig_la.write_image("ascn_timeline.svg")
 
 
 
821
  with col5_1:
822
+ with open('ascn_timeline.pdf','rb') as f:
823
+ st.download_button(
824
+ "Save As PDF",
825
+ f,
826
+ 'sonogram-timeline-'+currPlainName+'.pdf',
827
+ 'application/pdf',
828
+ key='download-pdf5',
829
+ on_click="ignore",
830
+ )
 
831
  with col5_2:
832
+ with open('ascn_timeline.svg','rb') as f:
833
+ st.download_button(
834
+ "Save As SVG",
835
+ f,
836
+ 'sonogram-timeline-'+currPlainName+'.svg',
837
+ 'image/svg+xml',
838
+ key='download-svg5',
839
+ on_click="ignore",
840
+ )
841
+ st.plotly_chart(fig_la, use_container_width=True,config=config)
842
 
843
  with bar1:
844
+ df2 = st.session_state.summaries[currFileIndex]["df2"]
 
845
  fig2_la = px.bar(df2, x="values", y="names", color="names", orientation='h',
846
  custom_data=["names","values"],title="Time Spoken by each Speaker",
847
  color_discrete_sequence=catColors+speakerColors)
 
862
  'Percentage of Time: %{customdata[1]:.2f}%'
863
  ])
864
  )
865
+
866
  col6_1, col6_2 = st.columns(2)
867
+ fig_la.write_image("ascn_bar.pdf")
868
+ fig_la.write_image("ascn_bar.svg")
 
 
 
869
  with col6_1:
870
+ with open('ascn_bar.pdf','rb') as f:
871
+ st.download_button(
872
+ "Save As PDF",
873
+ f,
874
+ 'sonogram-speaker-time-'+currPlainName+'.pdf',
875
+ 'application/pdf',
876
+ key='download-pdf6',
877
+ on_click="ignore",
878
+ )
 
879
  with col6_2:
880
+ with open('ascn_bar.svg','rb') as f:
881
+ st.download_button(
882
+ "Save As SVG",
883
+ f,
884
+ 'sonogram-speaker-time-'+currPlainName+'.svg',
885
+ 'image/svg+xml',
886
+ key='download-svg6',
887
+ on_click="ignore",
888
+ )
889
+ st.plotly_chart(fig2_la, use_container_width=True,config=config)
890
+
891
+ except ValueError:
892
+ pass
 
 
893
 
894
  if len(st.session_state.results) > 0:
895
  with st.expander("Multi-file Summary Data"):