Jiaaaaaaax commited on
Commit
b190eed
·
verified ·
1 Parent(s): 184c6e4

Update session_analysis.py

Browse files
Files changed (1) hide show
  1. session_analysis.py +265 -37
session_analysis.py CHANGED
@@ -67,13 +67,19 @@ def process_video_file(video_file):
67
  f.write(video_file.getbuffer())
68
 
69
  st.video(temp_path)
70
- st.info("Video uploaded successfully. Please note: automatic transcription is not yet implemented. Please provide transcript manually.")
71
 
72
  # Add manual transcript input
73
- transcript = st.text_area("Please enter the session transcript:", height=300)
74
- if transcript:
75
- st.session_state.current_transcript = transcript
76
- analyze_session_content(transcript)
 
 
 
 
 
 
77
 
78
  except Exception as e:
79
  st.error(f"Error processing video: {str(e)}")
@@ -87,13 +93,19 @@ def process_audio_file(audio_file):
87
  f.write(audio_file.getbuffer())
88
 
89
  st.audio(temp_path)
90
- st.info("Audio uploaded successfully. Please note: automatic transcription is not yet implemented. Please provide transcript manually.")
91
 
92
  # Add manual transcript input
93
- transcript = st.text_area("Please enter the session transcript:", height=300)
94
- if transcript:
95
- st.session_state.current_transcript = transcript
96
- analyze_session_content(transcript)
 
 
 
 
 
 
97
 
98
  except Exception as e:
99
  st.error(f"Error processing audio: {str(e)}")
@@ -170,23 +182,83 @@ def get_processing_step_name(step):
170
  return steps[step]
171
 
172
  def process_text_file(file):
 
173
  try:
174
- if file.name.endswith('.json'):
175
- content = json.loads(file.read().decode())
176
- transcript = extract_transcript_from_json(content)
177
- elif file.name.endswith('.docx'):
178
- doc = Document(file)
179
- transcript = '\n'.join([paragraph.text for paragraph in doc.paragraphs])
180
- else:
181
- transcript = file.read().decode()
182
-
183
- if transcript:
184
- st.session_state.current_transcript = transcript
185
- analyze_session_content(transcript)
186
-
 
 
 
 
187
  except Exception as e:
188
  st.error(f"Error processing file: {str(e)}")
189
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  def show_manual_input_form():
191
  st.subheader("Session Details")
192
 
@@ -741,13 +813,16 @@ def analyze_session_content(transcript):
741
  st.error(f"Error analyzing session content: {str(e)}")
742
 
743
  def show_analysis_results():
744
- """Display session analysis results"""
745
  if not st.session_state.analysis_results:
746
- st.warning("No analysis results available.")
747
  return
748
 
749
- st.header("Session Analysis Results")
750
-
 
 
 
 
751
  # Create tabs for different aspects of analysis
752
  tabs = st.tabs([
753
  "MI Adherence",
@@ -756,21 +831,174 @@ def show_analysis_results():
756
  "Session Flow",
757
  "Recommendations"
758
  ])
759
-
760
- # Parse analysis results (assuming structured response from AI)
761
- analysis = parse_analysis_results(st.session_state.analysis_results)
762
-
763
- # Display results in respective tabs
764
  with tabs[0]:
765
- show_mi_adherence_analysis(analysis.get('mi_adherence', {}))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
766
  with tabs[1]:
767
- show_technical_skills_analysis(analysis.get('technical_skills', {}))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
768
  with tabs[2]:
769
- show_client_language_analysis(analysis.get('client_language', {}))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
770
  with tabs[3]:
771
- show_session_flow_analysis(analysis.get('session_flow', {}))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
772
  with tabs[4]:
773
- show_recommendations(analysis.get('recommendations', {}))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774
 
775
  def parse_analysis_response(response_text):
776
  """Parse the AI response into structured analysis results"""
 
67
  f.write(video_file.getbuffer())
68
 
69
  st.video(temp_path)
70
+ st.info("Video uploaded successfully. Please provide transcript.")
71
 
72
  # Add manual transcript input
73
+ transcript = st.text_area("Enter the session transcript:", height=300)
74
+
75
+ # Add analyze button
76
+ if st.button("Analyze Transcript"):
77
+ if transcript:
78
+ with st.spinner('Analyzing transcript...'):
79
+ st.session_state.current_transcript = transcript
80
+ analyze_session_content(transcript)
81
+ else:
82
+ st.warning("Please enter a transcript before analyzing.")
83
 
84
  except Exception as e:
85
  st.error(f"Error processing video: {str(e)}")
 
93
  f.write(audio_file.getbuffer())
94
 
95
  st.audio(temp_path)
96
+ st.info("Audio uploaded successfully. Please provide transcript.")
97
 
98
  # Add manual transcript input
99
+ transcript = st.text_area("Enter the session transcript:", height=300)
100
+
101
+ # Add analyze button
102
+ if st.button("Analyze Transcript"):
103
+ if transcript:
104
+ with st.spinner('Analyzing transcript...'):
105
+ st.session_state.current_transcript = transcript
106
+ analyze_session_content(transcript)
107
+ else:
108
+ st.warning("Please enter a transcript before analyzing.")
109
 
110
  except Exception as e:
111
  st.error(f"Error processing audio: {str(e)}")
 
182
  return steps[step]
183
 
184
  def process_text_file(file):
185
+ """Process uploaded text file"""
186
  try:
187
+ # Read file content
188
+ content = file.getvalue().decode("utf-8")
189
+ st.session_state.current_transcript = content
190
+
191
+ # Display transcript with edit option
192
+ edited_transcript = st.text_area(
193
+ "Review and edit transcript if needed:",
194
+ value=content,
195
+ height=300
196
+ )
197
+
198
+ # Add analyze button
199
+ if st.button("Analyze Transcript"):
200
+ with st.spinner('Analyzing transcript...'):
201
+ st.session_state.current_transcript = edited_transcript
202
+ analyze_session_content(edited_transcript)
203
+
204
  except Exception as e:
205
  st.error(f"Error processing file: {str(e)}")
206
 
207
+ def parse_analysis_results(raw_results):
208
+ """Parse the raw analysis results into structured format"""
209
+ if isinstance(raw_results, dict):
210
+ return raw_results # Already parsed
211
+
212
+ try:
213
+ # If it's a string, try to extract structured data
214
+ analysis = {
215
+ 'mi_adherence_score': 0,
216
+ 'key_themes': [],
217
+ 'technique_usage': {},
218
+ 'strengths': [],
219
+ 'areas_for_improvement': [],
220
+ 'session_summary': ''
221
+ }
222
+
223
+ # Extract score (assuming it's in format "Score: XX")
224
+ score_match = re.search(r'Score:\s*(\d+)', raw_results)
225
+ if score_match:
226
+ analysis['mi_adherence_score'] = int(score_match.group(1))
227
+
228
+ # Extract themes (assuming they're listed after "Key Themes:")
229
+ themes_match = re.search(r'Key Themes:(.*?)(?=\n\n|\Z)', raw_results, re.DOTALL)
230
+ if themes_match:
231
+ themes = themes_match.group(1).strip().split('\n')
232
+ analysis['key_themes'] = [t.strip('- ') for t in themes if t.strip()]
233
+
234
+ # Extract techniques (assuming they're listed with counts)
235
+ techniques = re.findall(r'(\w+\s*\w*)\s*:\s*(\d+)', raw_results)
236
+ if techniques:
237
+ analysis['technique_usage'] = {t[0]: int(t[1]) for t in techniques}
238
+
239
+ # Extract strengths
240
+ strengths_match = re.search(r'Strengths:(.*?)(?=Areas for Improvement|\Z)', raw_results, re.DOTALL)
241
+ if strengths_match:
242
+ strengths = strengths_match.group(1).strip().split('\n')
243
+ analysis['strengths'] = [s.strip('- ') for s in strengths if s.strip()]
244
+
245
+ # Extract areas for improvement
246
+ improvements_match = re.search(r'Areas for Improvement:(.*?)(?=\n\n|\Z)', raw_results, re.DOTALL)
247
+ if improvements_match:
248
+ improvements = improvements_match.group(1).strip().split('\n')
249
+ analysis['areas_for_improvement'] = [i.strip('- ') for i in improvements if i.strip()]
250
+
251
+ # Extract summary
252
+ summary_match = re.search(r'Summary:(.*?)(?=\n\n|\Z)', raw_results, re.DOTALL)
253
+ if summary_match:
254
+ analysis['session_summary'] = summary_match.group(1).strip()
255
+
256
+ return analysis
257
+
258
+ except Exception as e:
259
+ st.error(f"Error parsing analysis results: {str(e)}")
260
+ return None
261
+
262
  def show_manual_input_form():
263
  st.subheader("Session Details")
264
 
 
813
  st.error(f"Error analyzing session content: {str(e)}")
814
 
815
  def show_analysis_results():
816
+ """Display the analysis results in the dashboard"""
817
  if not st.session_state.analysis_results:
 
818
  return
819
 
820
+ # Parse the results
821
+ analysis = parse_analysis_results(st.session_state.analysis_results)
822
+ if not analysis:
823
+ st.error("Unable to parse analysis results")
824
+ return
825
+
826
  # Create tabs for different aspects of analysis
827
  tabs = st.tabs([
828
  "MI Adherence",
 
831
  "Session Flow",
832
  "Recommendations"
833
  ])
834
+
835
+ # MI Adherence Tab
 
 
 
836
  with tabs[0]:
837
+ st.subheader("MI Adherence Score")
838
+ score = analysis.get('mi_adherence_score', 0)
839
+ create_gauge_chart(score)
840
+
841
+ col1, col2 = st.columns(2)
842
+ with col1:
843
+ st.subheader("Strengths")
844
+ for strength in analysis.get('strengths', []):
845
+ st.markdown(f"✅ {strength}")
846
+
847
+ with col2:
848
+ st.subheader("Areas for Improvement")
849
+ for area in analysis.get('areas_for_improvement', []):
850
+ st.markdown(f"🔄 {area}")
851
+
852
+ # Technical Skills Tab
853
  with tabs[1]:
854
+ st.subheader("MI Technique Usage")
855
+ technique_data = analysis.get('technique_usage', {})
856
+
857
+ # Create bar chart for technique usage
858
+ if technique_data:
859
+ fig = go.Figure(data=[
860
+ go.Bar(
861
+ x=list(technique_data.keys()),
862
+ y=list(technique_data.values()),
863
+ marker_color='rgb(26, 118, 255)'
864
+ )
865
+ ])
866
+
867
+ fig.update_layout(
868
+ title="Technique Usage Frequency",
869
+ xaxis_title="Technique",
870
+ yaxis_title="Count",
871
+ template="plotly_white"
872
+ )
873
+ st.plotly_chart(fig)
874
+
875
+ # Technique breakdown
876
+ for technique, count in technique_data.items():
877
+ with st.expander(f"{technique} ({count} instances)"):
878
+ st.write(get_technique_description(technique))
879
+
880
+ # Client Language Tab
881
  with tabs[2]:
882
+ st.subheader("Client Language Analysis")
883
+
884
+ # Create columns for different types of client language
885
+ col1, col2 = st.columns(2)
886
+
887
+ with col1:
888
+ st.markdown("### Change Talk 🌱")
889
+ change_talk = analysis.get('change_talk', [])
890
+ if change_talk:
891
+ for talk in change_talk:
892
+ st.markdown(f"- {talk}")
893
+ else:
894
+ st.info("No specific change talk identified")
895
+
896
+ with col2:
897
+ st.markdown("### Sustain Talk 🔄")
898
+ sustain_talk = analysis.get('sustain_talk', [])
899
+ if sustain_talk:
900
+ for talk in sustain_talk:
901
+ st.markdown(f"- {talk}")
902
+ else:
903
+ st.info("No specific sustain talk identified")
904
+
905
+ # Session Flow Tab
906
  with tabs[3]:
907
+ st.subheader("Session Flow Analysis")
908
+
909
+ # Display key themes
910
+ st.markdown("### Key Themes 🎯")
911
+ themes = analysis.get('key_themes', [])
912
+ for theme in themes:
913
+ st.markdown(f"- {theme}")
914
+
915
+ # Session structure
916
+ st.markdown("### Session Structure")
917
+ session_summary = analysis.get('session_summary', '')
918
+ if session_summary:
919
+ st.write(session_summary)
920
+
921
+ # Add timeline visualization if available
922
+ if 'timeline' in analysis:
923
+ create_session_timeline(analysis['timeline'])
924
+
925
+ # Recommendations Tab
926
  with tabs[4]:
927
+ st.subheader("Recommendations for Improvement")
928
+
929
+ # Priority recommendations
930
+ st.markdown("### Priority Areas 🎯")
931
+ for area in analysis.get('areas_for_improvement', [])[:3]: # Top 3 priorities
932
+ st.markdown(f"**1️⃣ {area}**")
933
+ st.markdown(get_improvement_suggestion(area))
934
+
935
+ # Specific action items
936
+ st.markdown("### Action Items ✅")
937
+ create_action_items(analysis)
938
+
939
+ # Resources
940
+ st.markdown("### Helpful Resources 📚")
941
+ show_relevant_resources(analysis)
942
+
943
+ def get_technique_description(technique):
944
+ """Return description for MI techniques"""
945
+ descriptions = {
946
+ "Open Questions": "Questions that allow for elaboration and cannot be answered with a simple yes/no.",
947
+ "Reflections": "Statements that mirror, rephrase, or elaborate on the client's speech.",
948
+ "Affirmations": "Statements that recognize client strengths and acknowledge behaviors that lead to positive change.",
949
+ "Summaries": "Statements that collect, link, and transition between client statements.",
950
+ "Information Giving": "Providing information with permission and in response to client needs.",
951
+ # Add more techniques as needed
952
+ }
953
+ return descriptions.get(technique, "Description not available")
954
+
955
+ def create_session_timeline(timeline_data):
956
+ """Create a visual timeline of the session"""
957
+ if not timeline_data:
958
+ st.info("Detailed timeline not available")
959
+ return
960
+
961
+ fig = go.Figure()
962
+ # Add timeline visualization code here
963
+ st.plotly_chart(fig)
964
+
965
+ def get_improvement_suggestion(area):
966
+ """Return specific suggestions for improvement areas"""
967
+ suggestions = {
968
+ "Open Questions": "Try replacing closed questions with open-ended ones. Instead of 'Did you exercise?', ask 'What kinds of physical activity have you been doing?'",
969
+ "Reflections": "Practice using more complex reflections by adding meaning or emotion to what the client has said.",
970
+ "Empathy": "Focus on seeing the situation from the client's perspective and verbalize your understanding.",
971
+ # Add more suggestions as needed
972
+ }
973
+ return suggestions.get(area, "Work on incorporating this element more intentionally in your sessions.")
974
+
975
+ def create_action_items(analysis):
976
+ """Create specific action items based on analysis"""
977
+ st.write("Based on the analysis, consider focusing on these specific actions:")
978
+
979
+ # Example action items
980
+ action_items = [
981
+ "Practice one new MI skill each session",
982
+ "Record and review your sessions",
983
+ "Focus on developing complex reflections",
984
+ "Track change talk/sustain talk ratio"
985
+ ]
986
+
987
+ for item in action_items:
988
+ st.checkbox(item)
989
+
990
+ def show_relevant_resources(analysis):
991
+ """Display relevant resources based on analysis"""
992
+ resources = [
993
+ {"title": "MI Practice Exercises", "url": "#"},
994
+ {"title": "Reflection Templates", "url": "#"},
995
+ {"title": "Change Talk Recognition Guide", "url": "#"},
996
+ {"title": "MI Community of Practice", "url": "#"}
997
+ ]
998
+
999
+ for resource in resources:
1000
+ st.markdown(f"[{resource['title']}]({resource['url']})")
1001
+
1002
 
1003
  def parse_analysis_response(response_text):
1004
  """Parse the AI response into structured analysis results"""