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

Update session_analysis.py

Browse files
Files changed (1) hide show
  1. session_analysis.py +186 -105
session_analysis.py CHANGED
@@ -61,25 +61,36 @@ def show_upload_section():
61
  def process_video_file(video_file):
62
  """Process uploaded video file"""
63
  try:
64
- # Save video temporarily
65
  temp_path = f"temp_video_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
 
 
66
  with open(temp_path, "wb") as f:
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)}")
@@ -785,42 +796,74 @@ def format_session_data(session_data):
785
  return formatted_text
786
 
787
  def analyze_session_content(transcript):
 
788
  try:
789
- # Initialize Gemini
 
 
 
 
790
  model = genai.GenerativeModel('gemini-pro')
791
 
792
- # Prepare the analysis prompt
793
- analysis_prompt = f"""
794
- {MI_SYSTEM_PROMPT}
795
-
796
- Please analyze the following therapy session transcript:
797
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
798
  {transcript}
799
-
800
- {SESSION_EVALUATION_PROMPT}
801
  """
802
 
803
- # Generate analysis
804
- response = model.generate_content(analysis_prompt)
805
-
806
- # Parse the response
807
- analysis_results = parse_analysis_response(response.text)
808
 
809
  # Store results in session state
810
- st.session_state.analysis_results = analysis_results
 
 
 
811
 
812
  except Exception as e:
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
@@ -835,110 +878,132 @@ def show_analysis_results():
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"""
@@ -1058,6 +1123,22 @@ def parse_analysis_response(response_text):
1058
  st.error(f"Error parsing analysis response: {str(e)}")
1059
  return None
1060
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1061
  def create_gauge_chart(score):
1062
  """Create a gauge chart for MI Adherence Score"""
1063
  fig = go.Figure(go.Indicator(
 
61
  def process_video_file(video_file):
62
  """Process uploaded video file"""
63
  try:
64
+ # Create a unique temporary file name
65
  temp_path = f"temp_video_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
66
+
67
+ # Save video temporarily
68
  with open(temp_path, "wb") as f:
69
  f.write(video_file.getbuffer())
70
 
71
+ # Display video
72
  st.video(temp_path)
 
73
 
74
+ # Add transcript input
75
+ transcript = st.text_area(
76
+ "Enter the session transcript:",
77
+ height=300,
78
+ help="Paste or type the transcript of the session here."
79
+ )
80
 
81
  # Add analyze button
82
  if st.button("Analyze Transcript"):
83
+ if transcript.strip():
84
  with st.spinner('Analyzing transcript...'):
 
85
  analyze_session_content(transcript)
86
  else:
87
  st.warning("Please enter a transcript before analyzing.")
88
+
89
+ # Clean up temporary file
90
+ try:
91
+ os.remove(temp_path)
92
+ except:
93
+ pass
94
 
95
  except Exception as e:
96
  st.error(f"Error processing video: {str(e)}")
 
796
  return formatted_text
797
 
798
  def analyze_session_content(transcript):
799
+ """Analyze the session transcript using Gemini"""
800
  try:
801
+ if not transcript:
802
+ st.warning("Please provide a transcript for analysis.")
803
+ return
804
+
805
+ # Configure the model
806
  model = genai.GenerativeModel('gemini-pro')
807
 
808
+ # Prepare prompt with structured output request
809
+ prompt = """
810
+ Analyze this MI (Motivational Interviewing) session transcript and provide analysis in the following structured format:
811
+
812
+ MI Adherence Score: [0-100]
813
+
814
+ Key Themes:
815
+ - [Theme 1]
816
+ - [Theme 2]
817
+ - [Theme 3]
818
+
819
+ Technique Usage:
820
+ - Open Questions: [count]
821
+ - Reflections: [count]
822
+ - Affirmations: [count]
823
+ - Summaries: [count]
824
+
825
+ Strengths:
826
+ - [Strength 1]
827
+ - [Strength 2]
828
+ - [Strength 3]
829
+
830
+ Areas for Improvement:
831
+ - [Area 1]
832
+ - [Area 2]
833
+ - [Area 3]
834
+
835
+ Change Talk Instances:
836
+ - [Example 1]
837
+ - [Example 2]
838
+
839
+ Sustain Talk Instances:
840
+ - [Example 1]
841
+ - [Example 2]
842
+
843
+ Session Summary:
844
+ [Brief summary of the session flow and key moments]
845
+
846
+ Transcript to analyze:
847
  {transcript}
 
 
848
  """
849
 
850
+ # Generate response
851
+ response = model.generate_content(prompt)
 
 
 
852
 
853
  # Store results in session state
854
+ st.session_state.analysis_results = response.text
855
+
856
+ # Trigger results display
857
+ show_analysis_results()
858
 
859
  except Exception as e:
860
+ st.error(f"Error analyzing session: {str(e)}")
861
+
862
 
863
  def show_analysis_results():
864
  """Display the analysis results in the dashboard"""
865
+ if 'analysis_results' not in st.session_state or not st.session_state.analysis_results:
866
+ st.info("No analysis results available. Please analyze a transcript first.")
 
 
 
 
 
867
  return
868
 
869
  # Create tabs for different aspects of analysis
 
878
  # MI Adherence Tab
879
  with tabs[0]:
880
  st.subheader("MI Adherence Score")
 
 
881
 
882
+ # Extract score from analysis results
883
+ score_match = re.search(r'MI Adherence Score:\s*(\d+)', st.session_state.analysis_results)
884
+ if score_match:
885
+ score = int(score_match.group(1))
886
+
887
+ # Create score gauge
888
+ fig = go.Figure(go.Indicator(
889
+ mode="gauge+number",
890
+ value=score,
891
+ domain={'x': [0, 1], 'y': [0, 1]},
892
+ gauge={'axis': {'range': [0, 100]},
893
+ 'bar': {'color': "rgb(26, 118, 255)"},
894
+ 'steps': [
895
+ {'range': [0, 33], 'color': "lightgray"},
896
+ {'range': [33, 66], 'color': "gray"},
897
+ {'range': [66, 100], 'color': "darkgray"}
898
+ ]}))
899
+ st.plotly_chart(fig)
900
+
901
+ # Extract and display strengths
902
+ strengths = re.findall(r'Strengths:\n((?:- .*\n)*)', st.session_state.analysis_results)
903
+ if strengths:
904
  st.subheader("Strengths")
905
+ strength_list = strengths[0].strip().split('\n')
906
+ for strength in strength_list:
907
+ if strength.startswith('- '):
908
+ st.markdown(f"✅ {strength[2:]}")
909
+
910
+ # Extract and display areas for improvement
911
+ improvements = re.findall(r'Areas for Improvement:\n((?:- .*\n)*)', st.session_state.analysis_results)
912
+ if improvements:
913
  st.subheader("Areas for Improvement")
914
+ improvement_list = improvements[0].strip().split('\n')
915
+ for improvement in improvement_list:
916
+ if improvement.startswith('- '):
917
+ st.markdown(f"🔄 {improvement[2:]}")
918
 
919
  # Technical Skills Tab
920
  with tabs[1]:
921
  st.subheader("MI Technique Usage")
 
922
 
923
+ # Extract technique counts
924
+ techniques = {
925
+ 'Open Questions': 0,
926
+ 'Reflections': 0,
927
+ 'Affirmations': 0,
928
+ 'Summaries': 0
929
+ }
930
+
931
+ for technique in techniques.keys():
932
+ count_match = re.search(f'{technique}:\s*(\d+)', st.session_state.analysis_results)
933
+ if count_match:
934
+ techniques[technique] = int(count_match.group(1))
935
+
936
+ # Create bar chart
937
+ fig = go.Figure(data=[
938
+ go.Bar(
939
+ x=list(techniques.keys()),
940
+ y=list(techniques.values()),
941
+ marker_color='rgb(26, 118, 255)'
942
  )
943
+ ])
944
 
945
+ fig.update_layout(
946
+ title="Technique Usage Frequency",
947
+ xaxis_title="Technique",
948
+ yaxis_title="Count",
949
+ template="plotly_white"
950
+ )
951
+ st.plotly_chart(fig)
952
 
953
  # Client Language Tab
954
  with tabs[2]:
955
  st.subheader("Client Language Analysis")
956
 
957
+ # Extract change talk
958
+ change_talk = re.findall(r'Change Talk Instances:\n((?:- .*\n)*)', st.session_state.analysis_results)
959
+ if change_talk:
 
960
  st.markdown("### Change Talk 🌱")
961
+ changes = change_talk[0].strip().split('\n')
962
+ for change in changes:
963
+ if change.startswith('- '):
964
+ st.markdown(f"- {change[2:]}")
965
+
966
+ # Extract sustain talk
967
+ sustain_talk = re.findall(r'Sustain Talk Instances:\n((?:- .*\n)*)', st.session_state.analysis_results)
968
+ if sustain_talk:
969
  st.markdown("### Sustain Talk 🔄")
970
+ sustains = sustain_talk[0].strip().split('\n')
971
+ for sustain in sustains:
972
+ if sustain.startswith('- '):
973
+ st.markdown(f"- {sustain[2:]}")
 
 
974
 
975
  # Session Flow Tab
976
  with tabs[3]:
977
  st.subheader("Session Flow Analysis")
978
 
979
+ # Extract key themes
980
+ themes = re.findall(r'Key Themes:\n((?:- .*\n)*)', st.session_state.analysis_results)
981
+ if themes:
982
+ st.markdown("### Key Themes 🎯")
983
+ theme_list = themes[0].strip().split('\n')
984
+ for theme in theme_list:
985
+ if theme.startswith('- '):
986
+ st.markdown(f"- {theme[2:]}")
 
 
 
987
 
988
+ # Extract session summary
989
+ summary_match = re.search(r'Session Summary:\n(.*?)(?=\n\n|\Z)', st.session_state.analysis_results, re.DOTALL)
990
+ if summary_match:
991
+ st.markdown("### Session Summary")
992
+ st.write(summary_match.group(1).strip())
993
 
994
  # Recommendations Tab
995
  with tabs[4]:
996
  st.subheader("Recommendations for Improvement")
997
 
998
+ # Display improvement areas as recommendations
999
+ if improvements:
1000
+ st.markdown("### Priority Areas 🎯")
1001
+ improvement_list = improvements[0].strip().split('\n')
1002
+ for i, improvement in enumerate(improvement_list[:3], 1):
1003
+ if improvement.startswith('- '):
1004
+ st.markdown(f"**{i}. {improvement[2:]}**")
1005
+ st.markdown(get_improvement_suggestion(improvement[2:]))
1006
+
 
 
 
 
1007
 
1008
  def get_technique_description(technique):
1009
  """Return description for MI techniques"""
 
1123
  st.error(f"Error parsing analysis response: {str(e)}")
1124
  return None
1125
 
1126
+ def get_improvement_suggestion(area):
1127
+ """Return specific suggestions for improvement areas"""
1128
+ suggestions = {
1129
+ "open questions": "Practice replacing closed questions with open-ended ones. For example:\n- Instead of: 'Did you exercise?'\n- Try: 'What kinds of physical activity have you been doing?'",
1130
+ "reflections": "Work on using more complex reflections by adding meaning or emotion to what the client has said. Try to make at least two complex reflections for every simple reflection.",
1131
+ "empathy": "Focus on seeing the situation from the client's perspective. Take time to verbalize your understanding of their emotions and experiences.",
1132
+ "summaries": "Use more collecting summaries to gather key points discussed and transition summaries to move between topics.",
1133
+ "affirmations": "Look for opportunities to genuinely affirm client strengths and efforts, not just outcomes."
1134
+ }
1135
+
1136
+ # Look for matching suggestions using partial string matching
1137
+ for key, value in suggestions.items():
1138
+ if key in area.lower():
1139
+ return value
1140
+ return "Focus on incorporating this element more intentionally in your sessions. Consider recording your sessions and reviewing them with a supervisor or peer."
1141
+
1142
  def create_gauge_chart(score):
1143
  """Create a gauge chart for MI Adherence Score"""
1144
  fig = go.Figure(go.Indicator(