def weathervane_screen(lines, duration):
    def find_overlap(lines, df):
        df['bout_index'] = np.nan
        continuous_bout_index = 0
        for row_num in range(df.shape[0]):
            df.at[row_num, 'bout_index'] = continuous_bout_index
            if row_num < df.shape[0] - 1:
                if not (df.iloc[row_num].loc['end_time'] >= df.iloc[row_num + 1].loc['start_time'] and
                        df.iloc[row_num].loc['end_time'] <= df.iloc[row_num + 1].loc['end_time']):
                    continuous_bout_index += 1
        new_df = pd.DataFrame()
        for bout_index in np.unique(df['bout_index']):
            bout_df = df[df['bout_index'] == bout_index]
            corr_rows = lines[(lines['start_time'] >= bout_df.iloc[0].loc['start_time']) & (
                        lines['start_time'] <= bout_df.iloc[-1].loc['end_time'])]
            curve_test_angle = corr_rows['angle'].values[1:]
            curve_test_bearing = corr_rows['bearing'].values[:-1]
            if not all(x > 0 for x in curve_test_angle * curve_test_bearing):
                continue
            x = np.abs(corr_rows['bearing'].values)
            y = corr_rows['start_time'].values
            corrcoef = pearsonr(x, y)
            if corrcoef[1] < 0.05 and corrcoef[0] < bear_corrcoef_threshold and corr_rows['distance'].min() < 20*scale:
                new_df = new_df.append(
                    {'condition': condition, 'trajectory_index': trajectory_index, 'corrcoef': corrcoef[0],
                     'start_time': corr_rows.iloc[0].loc['start_time'],
                     'end_time': corr_rows.iloc[-1].loc['start_time']}, ignore_index=True)

        return new_df

    out_df = pd.DataFrame()
    lines = lines[lines['speed'] != 0]
    lines = lines[lines['on_edge'] != 1]
    for condition in conditions:
        lines_condition = condition_filter(lines, condition)
        for trajectory_index in np.unique(lines_condition['trajectory_index']):
            print(trajectory_index)
            trajectory_df = pd.DataFrame()
            single_trajectory = lines_condition[lines_condition['trajectory_index'] == trajectory_index]
            for row_index in range(single_trajectory.shape[0]):
                corr_rows = single_trajectory[
                    (single_trajectory['start_time'] >= single_trajectory.iloc[row_index].loc['start_time']) & (
                                single_trajectory['start_time'] < single_trajectory.iloc[row_index].loc[
                            'start_time'] + duration)]
                if corr_rows.shape[0] >= 3:
                    curve_test_angle = corr_rows['angle'].values[1:]
                    curve_test_bearing = corr_rows['bearing'].values[:-1]
                    if not all(x > 0 for x in curve_test_angle * curve_test_bearing):
                        continue

                    x = np.abs(corr_rows['bearing'].values)
                    y = corr_rows['start_time'].values
                    corrcoef = pearsonr(x, y)
                    if corrcoef[1] < 0.05 and corrcoef[0] < bear_corrcoef_threshold:
                        trajectory_df = trajectory_df.append(
                            {'condition': condition, 'trajectory_index': trajectory_index, 'corrcoef': corrcoef[0],
                             'start_time': corr_rows.iloc[0].loc['start_time'],
                             'end_time': corr_rows.iloc[-1].loc['start_time']}, ignore_index=True)
            out_df = out_df.append(find_overlap(single_trajectory, trajectory_df), ignore_index=True)
    return out_df
def orthokinesis_screen_conc(lines, duration,conc_label):
    def find_overlap(lines, df):
        df['bout_index'] = np.nan
        continuous_bout_index = 0
        for row_num in range(df.shape[0]):
            df.at[row_num, 'bout_index'] = continuous_bout_index
            if row_num < df.shape[0] - 1:
                if not (df.iloc[row_num].loc['end_time'] >= df.iloc[row_num + 1].loc['start_time'] and
                        df.iloc[row_num].loc['end_time'] <= df.iloc[row_num + 1].loc['end_time']):
                    continuous_bout_index += 1
        new_df = pd.DataFrame()
        for bout_index in np.unique(df['bout_index']):
            bout_df = df[df['bout_index'] == bout_index]
            corr_rows = lines[(lines['start_time'] >= bout_df.iloc[0].loc['start_time']) & (
                        lines['start_time'] <= bout_df.iloc[-1].loc['end_time'])]
            x = corr_rows[conc_label].values
            y = corr_rows['speed'].values
            z = corr_rows['start_time'].values
            corrcoef = pearsonr(x, y)
            slow_down_corrcoef = pearsonr(y, z)
            if corrcoef[1] < 0.05 and corrcoef[0] < conc_corrcoef_threshold and slow_down_corrcoef[1] < 0.05 and slow_down_corrcoef[0] < slow_down_corrcoef_threshold and corr_rows['distance'].min() < 8*scale:
                new_df = new_df.append(
                    {'condition': condition, 'trajectory_index': trajectory_index, 'corrcoef': corrcoef[0],
                     'start_time': corr_rows.iloc[0].loc['start_time'],
                     'end_time': corr_rows.iloc[-1].loc['start_time']}, ignore_index=True)

        return new_df

    out_df = pd.DataFrame()
    lines = lines[lines['speed'] != 0]
    for condition in conditions:
        lines_condition = condition_filter(lines, condition)
        for trajectory_index in np.unique(lines_condition['trajectory_index']):
            print(trajectory_index)
            trajectory_df = pd.DataFrame()
            single_trajectory = lines_condition[lines_condition['trajectory_index'] == trajectory_index]
            for row_index in range(single_trajectory.shape[0]):
                corr_rows = single_trajectory[
                    (single_trajectory['start_time'] >= single_trajectory.iloc[row_index].loc['start_time']) & (
                                single_trajectory['start_time'] < single_trajectory.iloc[row_index].loc[
                            'start_time'] + duration)]
                if corr_rows.shape[0] >= 3:
                    x = corr_rows[conc_label].values
                    y = corr_rows['speed'].values
                    z = corr_rows['start_time'].values
                    corrcoef = pearsonr(x, y)
                    slow_down_corrcoef = pearsonr(y, z)
                    if corrcoef[1] < 0.05 and corrcoef[0] < conc_corrcoef_threshold and slow_down_corrcoef[1] < 0.05 and slow_down_corrcoef[0] < slow_down_corrcoef_threshold:
                        trajectory_df = trajectory_df.append(
                            {'condition': condition, 'trajectory_index': trajectory_index, 'corrcoef': corrcoef[0],
                             'start_time': corr_rows.iloc[0].loc['start_time'],
                             'end_time': corr_rows.iloc[-1].loc['start_time']}, ignore_index=True)
            out_df = out_df.append(find_overlap(single_trajectory, trajectory_df), ignore_index=True)
    return out_df
def screen2lines(lines,screen):
    out_df = pd.DataFrame()
    condition = -1
    trajectory_index = -1
    for row_num in range(screen.shape[0]):
        current_condition = screen.iloc[row_num].loc['condition']
        if current_condition != condition:
            condition_lines = condition_filter(lines, current_condition)
            condition = current_condition
        current_trajectory_index = screen.iloc[row_num].loc['trajectory_index']
        if current_trajectory_index != trajectory_index:
            single_trajectory = condition_lines[condition_lines['trajectory_index'] == current_trajectory_index]
            trajectory_index = current_trajectory_index
        temp_lines = single_trajectory[(single_trajectory['start_time'] >= screen.iloc[row_num].loc['start_time']) & (single_trajectory['start_time'] <= screen.iloc[row_num].loc['end_time'])]
        out_df = out_df.append(temp_lines, ignore_index=True)
    return out_df
def sharp_turn_screen(lines, duration):
    def find_overlap(lines, df, trajectory_index):
        df['bout_index'] = np.nan
        continuous_bout_index = 0
        for row_num in range(df.shape[0]):
            df.at[row_num, 'bout_index'] = continuous_bout_index
            if row_num < df.shape[0] - 1:
                if not (df.iloc[row_num].loc['end_time'] >= df.iloc[row_num + 1].loc['start_time'] and
                        df.iloc[row_num].loc['end_time'] <= df.iloc[row_num + 1].loc['end_time']):
                    continuous_bout_index += 1
        new_df = pd.DataFrame()
        for bout_index in np.unique(df['bout_index']):
            bout_df = df[df['bout_index'] == bout_index]
            corr_rows = lines[(lines['start_time'] >= bout_df.iloc[0].loc['start_time']) & (
                    lines['start_time'] <= bout_df.iloc[-1].loc['end_time'])]
            center = np.mean(corr_rows['point1'].values)
            dist = math.hypot(center[0] - corr_rows.iloc[0].loc['x_center'], center[1] - corr_rows.iloc[0].loc['y_center'])
            if_found = int(np.isnan(meta[(meta['condition'] == condition) & (meta['trajectory_index'] == trajectory_index)]['find_time']))
            found_ls = ['found', 'not_found']
            turn_sum = int(np.nansum(corr_rows['angle'].values))
            turn = (180 + turn_sum) % 360 - 180
            new_df = new_df.append(
                {'condition': condition, 'trajectory_index': trajectory_index,
                 'start_time': corr_rows.iloc[0].loc['start_time'],
                 'end_time': corr_rows.iloc[-1].loc['start_time'], 'distance': dist, 'found': found_ls[if_found], 'angle_sum': turn_sum, 'angle': turn}, ignore_index=True)

        return new_df

    def screen_trajectory(trajectory_index):
        print(trajectory_index)
        trajectory_df = pd.DataFrame()
        single_trajectory = lines_condition[lines_condition['trajectory_index'] == trajectory_index]
        for row_index in range(single_trajectory.shape[0]):
            corr_rows = single_trajectory[
                (single_trajectory['start_time'] >= single_trajectory.iloc[row_index].loc['start_time']) & (
                        single_trajectory['start_time'] < single_trajectory.iloc[row_index].loc[
                    'start_time'] + duration)]
            if corr_rows.shape[0] >= 3:
                if -180 in corr_rows['angle'].values or 180 in corr_rows['angle'].values:
                    continue
                turn_sum = np.nansum(corr_rows['angle'].values)
                length_sum = np.nansum(corr_rows['length'].values)
                if length_sum < 2 * scale:
                    continue
                if np.abs(turn_sum) > angle_threshold and length_sum < length_threshold:
                    trajectory_df = trajectory_df.append(
                        {'condition': condition, 'trajectory_index': trajectory_index,
                         'start_time': corr_rows.iloc[0].loc['start_time'],
                         'end_time': corr_rows.iloc[-1].loc['start_time']}, ignore_index=True)
        return find_overlap(single_trajectory, trajectory_df, trajectory_index)

    out_df = pd.DataFrame()
    lines = lines[lines['on_edge'] != 1]
    lines = lines[pd.notnull(lines['angle'])]
    # lines = lines[lines['speed'] != 0]
    for condition in conditions:
        lines_condition = condition_filter(lines, condition)

        results = Parallel(n_jobs=num_cores)(
            delayed(screen_trajectory)(trajectory_index) for trajectory_index in
            np.unique(lines_condition['trajectory_index']))
        for result in results:
            out_df = out_df.append(result, ignore_index=True)
    return out_df
    # radius = all_groupby['radius'].mean().values
    # g = sns.distplot(radius, kde=False, hist_kws=dict(edgecolor="w", linewidth=1), bins=5)
    # g.set(xlabel='millimeter * 10', ylabel='count')
    # plt.show()

    # exit()
    # *********************************************************************************************************************
    for condition in conditions:
        kde = np.load('{}_distribution_no_tail.npy'.format(condition))
        # fit_head(kde, condition)
        head_area(kde, 150)
    exit()
    # *********************************************************************************************************************
    num_cores = multiprocessing.cpu_count()
    results = Parallel(n_jobs=num_cores)(
        delayed(kde_gen)(condition_filter(all_lines, condition)['distance'] for condition in conditions))

    for condition in conditions:
        condition_line = condition_filter(all_lines, condition)
        kde_gen(condition_line['distance'])
        # plt.ylim([0, 0.02])
        # plt.xlim([0, 300])
        #
        # plt.show()
        # exit()
        # g = sns.distplot(condition_line['distance'], norm_hist=True)
        # g.set(xlabel='distance (millimeter * 10)', ylabel='density', title=condition)
        # plt.ylim([0, 0.02])
        # plt.xlim([0, 325])
        # # plt.legend(conditions)
        # plt.show()