def computeDistFromWindow(stimROI, testROI, fx, fy, conversion): numFrames = len(fx) # count frames out = np.zeros(numFrames) # allocate output array start, end = SZU.locateWindow(stimROI, testROI) # define window line segment pnt = np.zeros(2) # allocate fish position for k in range(0, numFrames): # loop through frames pnt[0] = fx[k] # x-coord of fish for this frame pnt[1] = fy[k] # y-coord dist, _ = SZU.pnt2line( pnt, start, end) # compute distance for this frame in pixels out[k] = dist * conversion # convert to mm and store return out, start, end
def compute_BTA(bouts_test, bouts_stim, output_test, output_stim, btaLength): # Get Info about each bout (Align on Peaks!!) peaks_test = bouts_test[:, 1] peaks_stim = bouts_stim[:, 1] peaks_test = peaks_test.astype(int) peaks_stim = peaks_stim.astype(int) # Allocate Space for BTAs BTA_test = np.zeros((np.size(peaks_test), 2 * btaLength, 2)) BTA_stim = np.zeros((np.size(peaks_stim), 2 * btaLength, 2)) # Pad OUTPUT variable for alignment padValue = np.median(output_test) padding = np.zeros(btaLength) + padValue output_test_padded = np.concatenate((padding, output_test, padding), axis=0) padValue = np.median(output_stim) padding = np.zeros(btaLength) + padValue output_stim_padded = np.concatenate((padding, output_stim, padding), axis=0) # Compute Burst Triggered Average (Auto-Corr) BTA_test[:, :, 0] = SZU.burst_triggered_alignment(peaks_test, output_test_padded, 0, btaLength * 2) BTA_stim[:, :, 0] = SZU.burst_triggered_alignment(peaks_stim, output_stim_padded, 0, btaLength * 2) # Compute Burst Triggered Average BTA_test[:, :, 1] = SZU.burst_triggered_alignment(peaks_test, output_stim_padded, 0, btaLength * 2) BTA_stim[:, :, 1] = SZU.burst_triggered_alignment(peaks_stim, output_test_padded, 0, btaLength * 2) return BTA_test, BTA_stim
import matplotlib.pyplot as plt import matplotlib.image as mpimg import scipy.misc as misc from scipy import stats # Import local modules import SZ_macros as SZM import SZ_video as SZV import SZ_utilities as SZU # Read Folder List folderListFile = base_path + r'\Python_ED\Social _Behaviour_Setup\PreProcessing' folderListFile = folderListFile + r'\SocialFolderList_PreProcessing_2017_08_25_subset.txt' control = False groups, ages, folderNames, fishStatus = SZU.read_folder_list(folderListFile) # Bulk analysis of all folders for idx,folder in enumerate(folderNames): # Get Folder Names NS_folder, S_folder, C_folder = SZU.get_folder_names(folder) # ---------------------- # Process Video (NS) SZV.pre_process_video_summary_images(NS_folder, False) # Check if this is a control experiment if control: # Process Video (NS_2) - Control
# #folderListFile = base_path + r'\Isolation_Experiments\Python_Analysis_7days_Isolation\Folder_list\SocialFolderList_PreProcessing_Isolation11_Controls.txt' #analysisFolder = base_path + r'\Isolation_Experiments\Python_Analysis_7days_Isolation\Analysis_folder\Controls' folderListFile = base_path + r'\Isolation_Experiments\Python_Analysis_7days_Isolation\Folder_list\SocialFolderList_PreProcessing_Isolation11_Isolated.txt' analysisFolder = base_path + r'\Isolation_Experiments\Python_Analysis_7days_Isolation\Analysis_folder\Isolated' # Plot Data plot = False # Set motion thresholds motionStartThreshold = 0.03 motionStopThreshold = 0.01 # Load Folder list File groups, ages, folderNames, fishStatus = SZU.read_folder_list(folderListFile) # Bulk analysis of all folders for idx, folder in enumerate(folderNames): # Get Folder Names NS_folder, S_folder, C_folder = SZU.get_folder_names(folder) # Load NS Test Crop Regions bonsaiFiles = glob.glob(NS_folder + '\*.bonsai') bonsaiFiles = bonsaiFiles[0] test_ROIs = BONSAI_ARK.read_bonsai_crop_rois(bonsaiFiles) NS_test_ROIs = test_ROIs[:, :] # Load S Test Crop Regions bonsaiFiles = glob.glob(S_folder + '\*.bonsai')
def analyze_single_fish_experiment(dataFolder, analysisFolder, group, age, fishStatus, save): # Get Folder Names NS_folder, S_folder, D_folder = SZU.get_folder_names(dataFolder); # Load SocialSide Defintion filename = NS_folder + '\\SocialSide.txt' NS_socialSide = np.genfromtxt(filename, delimiter=' ', skiprows=0) filename = S_folder + '\\SocialSide.txt' S_socialSide = np.genfromtxt(filename, delimiter=' ', skiprows=0) # Compare SocialSide Defintions betwen NS and S comp = NS_socialSide - S_socialSide if (np.sum(np.abs(comp)) != 0): print ("Social Side defintion mismatch!!") print ('Folder:', dataFolder) socialSide = S_socialSide else: socialSide = S_socialSide # Specify Social Angle socialAngle = [270,90,270,90,270,90] # Analyze Each of the 6 Fish per experiment for f in range(0,6): # Make Plot fig = plt.figure(figsize = (12,9), dpi = 150) fig.subplots_adjust(hspace=0.5) # Load Test Fish Tracking (Non_social control) filename = NS_folder + '\\tracking' + str(f+1) + '.csv' test_tracking_ns = SZU.load_tracking(filename) #Tracking: X, Y, Ort, Major, Minor, Area trackingErrors_test_ns = SZU.measure_tracking_errors(test_tracking_ns) X_test_ns = test_tracking_ns[:, 0] Y_test_ns = test_tracking_ns[:, 1] Ort_test_ns = test_tracking_ns[:, 2] # Quantify Social Position Bias (during Non-social condition) if socialSide[f] == 0: socialY_ns = Y_test_ns > 225 non_socialY_ns = Y_test_ns <= 225 else: socialY_ns = Y_test_ns < 225 non_socialY_ns = Y_test_ns >= 225 # Relative Angle w.r.t. social position RelOrt_test_ns = Ort_test_ns-socialAngle[f] for i in range(0,np.size(RelOrt_test_ns)): if RelOrt_test_ns[i] < 0: RelOrt_test_ns[i] = RelOrt_test_ns[i]+360 ort_hist_test_ns, edges_test_ns = np.histogram(RelOrt_test_ns[socialY_ns], 36, (0, 360)) # Load Test Fish Tracking (Social condition) filename = S_folder + '\\tracking' + str(f+1) + '.csv' test_tracking_s = SZU.load_tracking(filename) #Tracking: X, Y, Ort, Major, Minor, Area trackingErrors_test_s = SZU.measure_tracking_errors(test_tracking_s) X_test_s = test_tracking_s[:, 0] Y_test_s = test_tracking_s[:, 1] Ort_test_s = test_tracking_s[:, 2] # Quantify Social Position Bias (during Social condition) if socialSide[f] == 0: socialY_s = Y_test_s > 225 non_socialY_s = Y_test_s <= 225 else: socialY_s = Y_test_s < 225 non_socialY_s = Y_test_s >= 225 # Relative Angle w.r.t. social position RelOrt_test_s = Ort_test_s-socialAngle[f] for i in range(0,np.size(RelOrt_test_s)): if RelOrt_test_s[i] < 0: RelOrt_test_s[i] = RelOrt_test_s[i]+360 ort_hist_test_s, edges_test_s = np.histogram(RelOrt_test_s[socialY_s], 36, (0, 360)) # Load Stimulus Fish Tracking (Social condition) filename = S_folder + '\\Social_Fish\\tracking' + str(f+1) + '.csv' stim_tracking_s = SZU.load_tracking(filename) #Tracking: X, Y, Ort, Major, Minor, Area trackingErrors_stim_s = SZU.measure_tracking_errors(stim_tracking_s) X_stim_s = stim_tracking_s[:, 0] Y_stim_s = stim_tracking_s[:, 1] Ort_stim_s = stim_tracking_s[:, 2] # Relative Angle w.r.t. social position RelOrt_stim_s = Ort_stim_s-socialAngle[f] for i in range(0,np.size(RelOrt_stim_s)): if RelOrt_stim_s[i] < 0: RelOrt_stim_s[i] = RelOrt_stim_s[i]+360 ort_hist_stim_s, edges_stim_s = np.histogram(RelOrt_stim_s[socialY_s], 36, (0, 360)) # Compute Social Preference Index / Bias (Non-Social Condition) totalFrames = float(np.size(X_test_ns)) socialFrames = float(np.sum(socialY_ns)) nonSocialFrames = float(np.sum(non_socialY_ns)) SPI_ns = ((socialFrames-nonSocialFrames)/totalFrames) # Compute Social Preference Index / Bias (Social Condition) totalFrames = float(np.size(X_test_s)) socialFrames = float(np.sum(socialY_s)) nonSocialFrames = float(np.sum(non_socialY_s)) SPI_s = ((socialFrames-nonSocialFrames)/totalFrames) ## Compute Correlation (Social Condition, when on Social-Side) corrLength = 500 motion_filter = np.array([0.25, 0.25, 0.25, 0.25]) # Determine Movement (Test Fish) - NS Movement = SZU.motion_signal(X_test_ns, Y_test_ns, Ort_test_ns) #movement_test_ns = signal.fftconvolve(motion_filter, Movement) movement_test_ns = Movement movement_test_ns = movement_test_ns[socialY_ns] # Determine Movement (Test Fish) - S Movement = SZU.motion_signal(X_test_s, Y_test_s, Ort_test_s) #movement_test_s = signal.fftconvolve(motion_filter, Movement) movement_test_s = Movement movement_test_s = movement_test_s[socialY_s] # Determine Movement (Stimulus Fish) - S Movement = SZU.motion_signal(X_stim_s, Y_stim_s, Ort_stim_s) #movement_stim_s = signal.fftconvolve(motion_filter, Movement) movement_stim_s = Movement movement_stim_s = movement_stim_s[socialY_s] # Cross Correlate - Zero Pad the Test Array z = np.zeros(corrLength) zero_padded_test_ns = np.concatenate((z, movement_test_ns, z), axis = 0) zero_padded_test_s = np.concatenate((z, movement_test_s, z), axis = 0) zero_padded_stim_s = np.concatenate((z, movement_stim_s, z), axis = 0) zero_padded_test_s_rev = zero_padded_test_s[::-1] # Scramble/Reverse Test # Compute Reversed Correlation crcor = np.correlate(zero_padded_test_s, movement_stim_s, mode="valid") crcor_rev = np.correlate(zero_padded_test_s_rev, movement_stim_s, mode="valid") # Compute Auto-Correlations auto_corr_test_ns = np.correlate(zero_padded_test_ns, movement_test_ns, mode="valid") auto_corr_test_s = np.correlate(zero_padded_test_s, movement_test_s, mode="valid") auto_corr_stim_s = np.correlate(zero_padded_stim_s, movement_stim_s, mode="valid") ## Compute Burst-Triggered Average of Test and Stimulus Fish FPS = 100 btaOffset = 100 z = np.zeros(corrLength) # Extract the bouts data bouts_test_ns, numBouts_test_ns = SZU.extract_bouts_from_motion(movement_test_ns, 2.0) #boutFreq_test_s = FPS * (numBouts_test_s/totalFrames) bouts_test_s, numBouts_test_s = SZU.extract_bouts_from_motion(movement_test_s, 2.0) #boutFreq_test_s = FPS * (numBouts_test_s/totalFrames) bouts_stim_s, numBouts_stim_s = SZU.extract_bouts_from_motion(movement_stim_s, 2.0) #boutFreq_stim_s = FPS * (numBouts_stim_s/totalFrames) peaks_test_ns = bouts_test_ns[:, 1] peaks_test_s = bouts_test_s[:, 1] peaks_stim_s = bouts_stim_s[:, 1] zero_padded = np.concatenate((movement_test_s, z), axis = 0) aligned = SZU.burst_triggered_alignment(peaks_stim_s, zero_padded, btaOffset, corrLength) BTA_test_s = np.mean(aligned, axis = 0) aligned = SZU.burst_triggered_alignment(peaks_test_s, zero_padded, btaOffset, corrLength) BTA_self_test_s = np.mean(aligned, axis = 0) zero_padded = np.concatenate((movement_stim_s, z), axis = 0) aligned = SZU.burst_triggered_alignment(peaks_test_s, zero_padded, btaOffset, corrLength) BTA_stim_s = np.mean(aligned, axis = 0) aligned = SZU.burst_triggered_alignment(peaks_stim_s, zero_padded, btaOffset, corrLength) BTA_self_stim_s = np.mean(aligned, axis = 0) # Plot Tracking # ---------------#---------------- # # Plot Test Non-Social Tracking plt.subplot(3, 3, 1) plt.plot(X_test_ns[non_socialY_ns],Y_test_ns[non_socialY_ns], '.', markersize = 1, color = [0.0,0.0,0.0,0.05]) plt.plot(X_test_ns[socialY_ns],Y_test_ns[socialY_ns], '.', markersize = 1, color = [1.0,0.0,0.0,0.05]) plt.axis([0, 180, 0, 450]) plt.title('Test Fish: Non-Social Condition\nSPI= %.2f' % SPI_ns, fontsize=8) ax = plt.gca() ax.invert_yaxis() plt.tick_params(labelsize = 6) # Plot Test Social Tracking plt.subplot(3, 3, 2) plt.plot(X_test_s[non_socialY_s],Y_test_s[non_socialY_s], '.', markersize = 1, color = [0.0,0.0,0.0,0.05]) plt.plot(X_test_s[socialY_s],Y_test_s[socialY_s], '.', markersize = 1, color = [1.0,0.0,0.0,0.05]) plt.axis([0, 180, 0, 450]) plt.title('Test Fish: Social Condition\nSPI= %.2f' % SPI_s, fontsize=8) ax = plt.gca() ax.invert_yaxis() plt.tick_params(labelsize = 6) # Plot Stimulus Fish Social Tracking plt.subplot(3, 3, 3) plt.plot(X_stim_s,Y_stim_s, '.', markersize = 1, color = [0.0,0.0,0.0,0.05]) plt.axis([0, 180, 0, 180]) plt.title('Stimulus Fish: Social Condition\n', fontsize=8) ax = plt.gca() ax.invert_yaxis() plt.tick_params(labelsize = 6) # Plot Orientation Histogram # ---------------#---------------- # # Make Orientation Plot, correct for social fish position plt.subplot(3, 3, 4, projection='polar') SZU.polar_orientation(RelOrt_test_ns[socialY_ns]) plt.title('Orientation Histogram (social side)\n', fontsize=8) plt.tick_params(labelsize = 6) # Make Orientation Plot, correct for social fish position plt.subplot(3, 3, 5, projection='polar') SZU.polar_orientation(RelOrt_test_s[socialY_s]) plt.title('Orientation Histogram (social side)\n', fontsize=8) plt.tick_params(labelsize = 6) # Make Orientation Plot, correct for social fish position plt.subplot(3, 3, 6, projection='polar') SZU.polar_orientation(RelOrt_stim_s[socialY_s]) plt.title('Orientation Histogram (test fish on social side)\n', fontsize=8) plt.tick_params(labelsize = 6) # Plot Correlation and Burst-Triggered Averages # ------------------------#---------------------------- # # Plot correlation and reversed correlation corrAxis = range(0, (corrLength*2)+1) corrAxis = np.array(corrAxis)-corrLength btaTaxis = range(0, corrLength) btaTaxis = np.array(btaTaxis)-btaOffset plt.subplot(3, 3, 8) plt.plot(corrAxis, crcor_rev, 'y') plt.plot(corrAxis, crcor, 'g') plt.title('Cross Correlation (test fish on social side)\n', fontsize=8) plt.tick_params(labelsize = 6) # Plot BTA of test fish movement triggered on stimulus fish "burst peaks" plt.subplot(3, 3, 7) plt.plot(btaTaxis, BTA_test_s, 'k') plt.title('Stimulus-Fish-Burst Triggered Average of Test Fish Motion\n', fontsize=8) plt.tick_params(labelsize = 6) # Plot BTA of stimulus fish movement triggered on test fish "burst peaks" plt.subplot(3, 3, 9) plt.plot(btaTaxis, BTA_stim_s, 'k') plt.title('Test-Fish-Burst Triggered Average of Stimulus Fish Motion\n', fontsize=8) plt.tick_params(labelsize = 6) # Save Figure and Data if save: # Prepare Summary Data orts = np.vstack((ort_hist_test_ns, ort_hist_test_s, ort_hist_stim_s)) correlations = np.vstack((crcor, crcor_rev, auto_corr_test_ns, auto_corr_test_s, auto_corr_stim_s)) peaks = [peaks_test_ns, peaks_test_s, peaks_stim_s] btas = np.vstack((BTA_test_s, BTA_stim_s, BTA_self_test_s, BTA_self_stim_s)) filename = analysisFolder + '\\' + str(np.int(group)) + '_' + str(f) +'.png' plt.savefig(filename, dpi=300) plt.close('all') # Save Correlation Data filename = analysisFolder + '\\' + str(np.int(group)) + '_' + str(f) +'.npz' summary = np.array([socialFrames, SPI_ns, SPI_s]) np.savez(filename, summary, orts, correlations, btas, peaks) # End of Loop return 0
def correlate_social_responses_folder(folderName, plot, save): # Specifiy Folder filename = folderName + '\\SocialSide.txt' socialSide = np.genfromtxt(filename, delimiter=' ', skiprows=0) socialAngle = [270,90,270,90,270,90] """ Summary Data Structure: 0 - Tracking Errors Social 1 - AvgSpeedSocial 2 - MaxOrtSocial 3 - BoutFreqSocial 4 - Correlation """ summaryData = np.zeros((6, 5)) corrLength = 500 crcorrs = np.zeros((6,2*corrLength+1)) if plot: plt.figure("CROSSCOR") plt.figure("BTA") plt.figure("BDIST") socialComparison = [1,2,3,4,5,6] for f in range(0,6): # Load Test Fish Tracking filename = folderName + '\\tracking' + str(f+1) + '.csv' test_tracking = SZU.load_tracking(filename) #Tracking: X, Y, Ort, Major, Minor, Area trackingErrorsTest = SZU.measure_tracking_errors(test_tracking) # Extract Tracking Variables X_test = test_tracking[:, 0] Y_test = test_tracking[:, 1] Ort_test = test_tracking[:, 2] # Load Social Fish Tracking filename = folderName + '\\Social_Fish\\tracking' + str(socialComparison[f]) + '.csv' social_tracking = SZU.load_tracking(filename) #Tracking: X, Y, Ort, Major, Minor, Area trackingErrorsSocial = SZU.measure_tracking_errors(social_tracking) # Extract Tracking Variables X_social = social_tracking[:, 0] Y_social = social_tracking[:, 1] Ort_social = social_tracking[:, 2] # Compute Useful Measurements (SOCIAL) speedXY = SZU.compute_speed(X_social, Y_social) avgSpeedSocial = np.mean(speedXY) # Relative Angle w.r.t. social position RelOrt = Ort_social-socialAngle[f] for i in range(0,np.size(RelOrt)): if RelOrt[i] < 0: RelOrt[i] = RelOrt[i]+360 ort_hist, edges = np.histogram(RelOrt, 18, (0, 360)) maxOrtSocial = edges[np.argmax(ort_hist)] # Determine when Test fish is in "Social Y Position" if socialSide[f] == 0: socialY = Y_test > 225 non_socialY = Y_test < 225 else: socialY = Y_test < 225 non_socialY = Y_test > 225 totalFrames = float(np.size(X_test)) socialFrames = float(np.sum(socialY)) nonSocialFrames = float(np.sum(non_socialY)) SPI = ((socialFrames-nonSocialFrames)/totalFrames) # Determine when Test fish can SEE (view) in "Social Fish" socialView = (RelOrt > 225) + (RelOrt < 135) socialView = socialView * socialY # Determine Movement Movement_test = SZU.motion_signal(X_test, Y_test, Ort_test) motion_filter = np.array([0.25, 0.25, 0.25, 0.25]) output = signal.fftconvolve(motion_filter, Movement_test) BinaryMovement_Test = output > 2.0 BinaryMovement_Test = BinaryMovement_Test.astype(float) Movement_social = SZU.motion_signal(X_social, Y_social, Ort_social) motion_filter = np.array([0.25, 0.25, 0.25, 0.25]) output = signal.fftconvolve(motion_filter, Movement_social) BinaryMovement_Social = output > 2.0 BinaryMovement_Social = BinaryMovement_Social.astype(float) # Only accept trials on Social Side # Movement_test_valid = Movement_test[socialY] # Movement_social_valid = Movement_social[socialY] # BinaryMovement_Test = BinaryMovement_Test[socialY] # BinaryMovement_Social = BinaryMovement_Social[socialY] # Zero Mean #BinaryMovement_Test = BinaryMovement_Test/np.mean(BinaryMovement_Test) #BinaryMovement_Social = BinaryMovement_Social/np.mean(BinaryMovement_Social) # Cross Correlate - Zero Pad the Test Array z = np.zeros(corrLength) zero_padded = np.concatenate((z, BinaryMovement_Test, z), axis = 0) # Scramble/Reverse Test zero_padded_rev = zero_padded[::-1] # Social View zero_padded_view = np.concatenate((z, BinaryMovement_Test[socialView], z), axis = 0) crcor = np.correlate(zero_padded, BinaryMovement_Social, mode="valid") crcor_rev = np.correlate(zero_padded_rev, BinaryMovement_Social, mode="valid") crcor_view = np.correlate(zero_padded_view, BinaryMovement_Social[socialView], mode="valid") # Normalize by reversed crccor?? # Quantify peakiness (central 51 (+/- 250 ms) vs outer 51) signalRange = range(corrLength-24, corrLength+27) # noiseRange1 = range(0, 50) # noiseRange2 = range((corrLength*2)-50, (corrLength*2)) # noise = (np.std(crcor[noiseRange1]) + np.std(crcor[noiseRange2]))/2 sig = np.std(crcor[signalRange]) noise = np.std(crcor_rev[signalRange]) corrVal = sig/noise # Compute Synchrony : probabilty that they are moving at the same time vs. random chance #percentMoving_test = np.sum(BinaryMovement_Test) / totalFrames #percentMoving_social = np.sum(BinaryMovement_Social) / totalFrames #prob_random = percentMoving_test * percentMoving_social #prob_actual = np.sum(BinaryMovement_Test * BinaryMovement_Social) / totalFrames percentMoving_test = np.sum(BinaryMovement_Test[socialView]) / np.sum(socialView) percentMoving_social = np.sum(BinaryMovement_Social[socialView]) / np.sum(socialView) prob_random = percentMoving_test * percentMoving_social prob_actual = np.sum(BinaryMovement_Test[socialView] * BinaryMovement_Social[socialView]) / np.sum(socialView) CorrReport = 'Corr: ' + str(round(corrVal,3)) + ' Rand: ' + str(round(prob_random*100, 2)) + ' Act: ' + str(round(prob_actual*100,2)) # Extract Bouts (Social) FPS = 100 bouts_social, numBouts = SZU.extract_bouts(X_social, Y_social, Ort_social, 2) boutFreqSocial = FPS * (numBouts/totalFrames) bouts_test, numBouts = SZU.extract_bouts(X_test, Y_test, Ort_test, 2) # Bout Triggered Average starts_social = bouts_social[:, 0] zero_padded = np.concatenate((Movement_test, z), axis = 0) aligned = SZU.burst_triggered_alignment(starts_social, zero_padded, 100, corrLength) BTA_test = np.mean(aligned, axis = 0) starts_test = bouts_test[:, 0] zero_padded = np.concatenate((Movement_social, z), axis = 0) aligned = SZU.burst_triggered_alignment(starts_test, zero_padded, 100, corrLength) BTA_social = np.mean(aligned, axis = 0) Distance_Social2Test = SZU.find_dist_to_nearest_index(starts_social, starts_test) Distance_Test2Social = SZU.find_dist_to_nearest_index(starts_test, starts_social) DSt_hist, DSt_edges = np.histogram(Distance_Social2Test, corrLength*2, (-corrLength,corrLength)) DTs_hist, DTs_edges = np.histogram(Distance_Test2Social, corrLength*2, (-corrLength,corrLength)) if (plot or save): # Make Position Plot plt.figure("CROSSCOR") plt.subplot(2, 3, f+1) plt.plot(crcor_rev, 'r') plt.plot(crcor_view, 'g') plt.plot(crcor) plt.title(CorrReport) plt.figure("BTA") plt.subplot(2, 3, f+1) plt.plot(BTA_test, 'r') plt.plot(BTA_social, 'b') plt.figure("BDIST") plt.subplot(2, 3, f+1) plt.plot(DSt_edges[0:-1], DSt_hist, 'r') plt.plot(DTs_edges[0:-1], DTs_hist, 'b') # Add Summary Data """ Summary Data Structure: 0 - Tracking Errors Social 1 - AvgSpeedSocial 2 - MaxOrtSocial 3 - BoutFreqSocial 4 - Correlation """ summaryData[f][0] = trackingErrorsSocial # Tracking Errors Social summaryData[f][1] = avgSpeedSocial # AvgSpeedSocial summaryData[f][2] = maxOrtSocial # MaxOrtSocial summaryData[f][3] = boutFreqSocial # BoutFreqSocial summaryData[f][4] = corrVal # Correlation crcorrs[f,:] = crcor # End of Loop if save: # Check of Analysis Folder analysisFolder = folderName + '\\Analysis' if not os.path.exists(analysisFolder): os.makedirs(analysisFolder) plt.figure("CROSSCOR") filename = analysisFolder + '\\CROSSCOR.png' plt.savefig(filename) plt.figure("BTA") filename = analysisFolder + '\\BTA.png' plt.savefig(filename) plt.figure("BDIST") filename = analysisFolder + '\\BDIST.png' plt.savefig(filename) plt.close('all') return summaryData, crcorrs
def analyze_bouts(testFolder, testNumber, stimFolder, stimNumber, visibleFrames, btaLength, threshold, testROI, stimROI): # Analyze Test trackingFile = testFolder + r'\tracking' + str(testNumber) + '.npz' data = np.load(trackingFile) tracking = data['tracking'] fx_test = tracking[:, 0] fy_test = tracking[:, 1] bx_test = tracking[:, 2] by_test = tracking[:, 3] ex_test = tracking[:, 4] ey_test = tracking[:, 5] area_test = tracking[:, 6] ort_test = tracking[:, 7] motion_test = tracking[:, 8] # Analyze Stim trackingFile = stimFolder + r'\tracking' + str(stimNumber) + '.npz' data = np.load(trackingFile) tracking = data['tracking'] fx_stim = tracking[:, 0] fy_stim = tracking[:, 1] bx_stim = tracking[:, 2] by_stim = tracking[:, 3] ex_stim = tracking[:, 4] ey_stim = tracking[:, 5] area_stim = tracking[:, 6] ort_stim = tracking[:, 7] motion_stim = tracking[:, 8] # Filter Tracking based on Social Frames (set to 0) - interpolate? motion_test[motion_test < 0.0] = 0.0 motion_stim[motion_stim < 0.0] = 0.0 # Compute Signal for bout detection (smoothed motion signal) bout_filter = np.array([0.25, 0.25, 0.25, 0.25]) boutSignal_test = signal.fftconvolve(motion_test, bout_filter, 'same') boutSignal_stim = signal.fftconvolve(motion_stim, bout_filter, 'same') # Determine Threshold levels # - Determine the largest 100 values and take the median # - Use 10% of max level, divide by 10, for the base threshold (sigma) sorted_motion = np.sort(motion_test) max_norm = np.median(sorted_motion[-100:]) sigma_test = max_norm / 10 threshold_test = sigma_test * threshold # - - - - print(threshold_test, max_norm) # - - - - sorted_motion = np.sort(motion_stim) max_norm = np.median(sorted_motion[-100:]) sigma_stim = max_norm / 10 threshold_stim = sigma_stim * threshold # Extract Bouts from Tracking Data bouts_test = SZU.extract_bouts_from_motion(bx_test, by_test, ort_test, boutSignal_test, threshold_test, threshold_test - sigma_test, testROI, True) bouts_stim = SZU.extract_bouts_from_motion(bx_stim, by_stim, ort_stim, boutSignal_stim, threshold_stim, threshold_stim - sigma_stim, stimROI, False) # Get Info about each bout (Align on STARTS!!) peaks_test = bouts_test[:, 1] peaks_stim = bouts_stim[:, 1] peaks_test = peaks_test.astype(int) peaks_stim = peaks_stim.astype(int) # Position at bout onset, offset # On Social(Visible side) at bout onset visible_testDuringStim = visibleFrames[peaks_stim] visible_stimDuringTest = visibleFrames[peaks_test] # Orientation of other fish during bout Peak # Zero degrees is towards bout generating fish, 180 is away, 90 is facing with REye, -90 is LEye # Seperate Orientations based on Chamber (1-6) # 1 - test right # 2 - test left # 3 - test right # 4 - test left # 5 - test right # 6 - test left ortOfTestDuringStim = ort_test[peaks_stim] ortOfStimDuringTest = ort_stim[peaks_test] # Adjust orientations so 0 is always pointing towards "other" fish if testNumber % 2 == 0: # Test Fish facing Left for i, ort in enumerate(ortOfTestDuringStim): if ort >= 0: ortOfTestDuringStim[i] = ort - 180 else: ortOfTestDuringStim[i] = ort + 180 if stimNumber % 2 == 1: # Stim fish facing Left for i, ort in enumerate(ortOfStimDuringTest): if ort >= 0: ortOfStimDuringTest[i] = ort - 180 else: ortOfStimDuringTest[i] = ort + 180 # Concatenate into Bouts Structure bouts_test = np.hstack( (bouts_test, np.transpose(np.atleast_2d(visible_stimDuringTest)))) bouts_stim = np.hstack( (bouts_stim, np.transpose(np.atleast_2d(visible_testDuringStim)))) bouts_test = np.hstack( (bouts_test, np.transpose(np.atleast_2d(ortOfStimDuringTest)))) bouts_stim = np.hstack( (bouts_stim, np.transpose(np.atleast_2d(ortOfTestDuringStim)))) return bouts_test, bouts_stim