示例#1
0
 def __call__(self, x):
     return PchipInterpolator.__call__(self, x, 1)
示例#2
0
 def __call__(self, x):
     return PchipInterpolator.__call__(self, x, 1)
示例#3
0
def read_excel_data_to_spline(read_excel_file, write_dir, discrete_points, spline_selector):
    cutoff = [10,100]
    # read_excel_file part
    df = pd.read_excel(read_excel_file, sheet_name='raw', header=[0, 1], index_col=0)

    # take only strain columns and make into a new df
    strain = df.xs('Strain (%)', level='Data', axis=1)
    strain = strain.values.T.tolist()  # .T to ensure that each sub list is along the column rather than rows of the df

    # strain store is a list of 1d ndarray, with each inner list being one set of strain data for one experiment
    strain_store = []
    for single_exp in strain:
        strain_single = [x for x in single_exp if not np.isnan(x)]
        strain_store.append(np.array(strain_single))

    # Similar to the above process, but repeat for relative resistance instead
    r = df.xs('R', level='Data', axis=1)
    r = r.values.T.tolist()
    r_store = []
    for single_exp in r:
        r_single = [x for x in single_exp if not np.isnan(x)]
        r_store.append(r_single)

    # Calculation of metrics for each experiment
    summary_store = []
    cutoff_store = []
    cutoff_store2 = []  # second method to do cutoff
    plot_store = []
    gf20_store = []
    for strain, r in zip(strain_store, r_store):
        eval_x = np.linspace(0, strain[-1], num=discrete_points)  # To evaluate spline at
        eval_x_plot = np.linspace(0, strain[-1], num=100)  # For plotting

        if spline_selector == 1:
            spline = PchipInterpolator(strain, r)
            linear_spline = interp1d(strain, r)
            # Getting GF for 20 points
            gf = np.minimum(np.concatenate(
                (
                    (linear_spline.__call__(eval_x[:-1]+0.01)-linear_spline.__call__(eval_x[:-1]))*100/0.01,
                                [(linear_spline.__call__(eval_x[-1])-linear_spline.__call__(eval_x[-1]-0.01))*100/0.01]
                )
            ), 1e6)
            # Store the processed labels. Labels for one example is 1d ndarray of
            # [End_point of strain curve, r1, r2, r3, ... , r_end]
            y_discrete = spline.__call__(eval_x)
            gradient_store = (y_discrete[1:] - y_discrete[:-1])/(eval_x[1]-eval_x[0]) * 100
            # If indexError occurs ==> np.where found nothing ==> there is no points with the required gradient
            # So just put the end point as the answer.
            try:
                cutoff_one = eval_x[np.where(gradient_store>=cutoff[0])[0][0]]
            except IndexError:
                cutoff_one = eval_x[-1]
            try:
                cutoff_two = eval_x[np.where(gradient_store >=cutoff[1])[0][0]]
            except IndexError:
                cutoff_two = eval_x[-1]
            cutoff_store.append([cutoff_one, cutoff_two, strain[-1]])
            summary_store.append(np.concatenate([[strain[-1]], y_discrete]))
            plot_store.append([eval_x_plot, spline.__call__(eval_x_plot)])
            gf20_store.append(gf)
        elif spline_selector == 2:
            # NOT IN USE
            # csaps implementation
            fitted_curve = csaps.UnivariateCubicSmoothingSpline(strain, r, smooth=0.7)
            summary_store.append(np.concatenate([[strain[-1]], fitted_curve(eval_x)]))
            plot_store.append([eval_x_plot, fitted_curve(eval_x_plot)])
        elif spline_selector == 3:
            # NOT IN USE
            # Scripy implementation
            spline = CubicSpline(strain, r)
            # Store the processed labels. Labels for one example is 1d ndarray of
            # [End_point of strain curve, r1, r2, r3, ... , r_end]
            summary_store.append(np.concatenate([[strain[-1]], spline.__call__(eval_x)]))
            plot_store.append([eval_x_plot, spline.__call__(eval_x_plot)])

        # Second cutoff method
        r = np.array(r)
        strain = np.array(strain)
        gf_store = (r[1:] - r[:-1])/(strain[1:] - strain[:-1]) * 100
        if gf_store[-1]<-1:
            cutoff_one = -1
            cutoff_two = -1
        else:
            try:
                cut_idx = np.where(gf_store>=cutoff[0])[0][0]
                if strain[cut_idx] > 0:
                    cutoff_one = strain[cut_idx]
                else:
                    cutoff_one = strain[cut_idx+1]
            except IndexError:
                cutoff_one = strain[-1]
            try:
                cut_idx = np.where(gf_store>=cutoff[1])[0][0]
                if strain[cut_idx] > 0:
                    cutoff_two = strain[cut_idx]
                else:
                    cutoff_two = strain[cut_idx+1]
            except IndexError:
                cutoff_two = strain[-1]
        cutoff_store2.append([cutoff_one, cutoff_two, strain[-1]])



    # Print to write_excel_file


    excel_name = write_dir + '/results.xlsx'
    wb = openpyxl.Workbook()
    wb.create_sheet('points')
    ws = wb['points']

    header = np.array(range(np.shape(strain_store)[0])) + 1  # Index to label Exp 1, 2, 3, ...
    columns = list(range(0,1+discrete_points))
    columns[0] = 'END'
    header = list(header)
    df_write = pd.DataFrame(summary_store, index=header, columns=columns)

    rows = dataframe_to_rows(df_write)
    for r_idx, row in enumerate(rows, 1):
        for c_idx, value in enumerate(row, 1):
            ws.cell(row=r_idx + 1, column=c_idx, value=value)

    wb.create_sheet('gf20')
    ws = wb['gf20']

    header = np.array(range(np.shape(strain_store)[0])) + 1  # Index to label Exp 1, 2, 3, ...
    columns = list(range(1,1+discrete_points))
    header = list(header)
    df_write = pd.DataFrame(gf20_store, index=header, columns=columns)

    rows = dataframe_to_rows(df_write)
    for r_idx, row in enumerate(rows, 1):
        for c_idx, value in enumerate(row, 1):
            ws.cell(row=r_idx + 1, column=c_idx, value=value)

    wb.create_sheet('cutoff')
    ws = wb['cutoff']

    header = np.array(range(np.shape(strain_store)[0])) + 1  # Index to label Exp 1, 2, 3, ...
    columns = ['cut={}'.format(x) for x in cutoff] + ['END']
    header = list(header)
    df_write = pd.DataFrame(cutoff_store, index=header, columns=columns)

    rows = dataframe_to_rows(df_write)
    for r_idx, row in enumerate(rows, 1):
        for c_idx, value in enumerate(row, 1):
            ws.cell(row=r_idx + 1, column=c_idx, value=value)

    wb.save(excel_name)
    wb.close()

    wb.create_sheet('cutoff2')
    ws = wb['cutoff2']

    header = np.array(range(np.shape(strain_store)[0])) + 1  # Index to label Exp 1, 2, 3, ...
    columns = ['cut={}'.format(x) for x in cutoff] + ['END']
    header = list(header)
    df_write = pd.DataFrame(cutoff_store2, index=header, columns=columns)

    rows = dataframe_to_rows(df_write)
    for r_idx, row in enumerate(rows, 1):
        for c_idx, value in enumerate(row, 1):
            ws.cell(row=r_idx + 1, column=c_idx, value=value)

    wb.save(excel_name)
    wb.close()

    # Plotting
    for idx, [strain, r, plot, summary] in enumerate(zip(strain_store, r_store, plot_store, summary_store)):
        plt.scatter(strain, r, c='r', marker='x', label='Expt. Points')
        plt.plot(plot[0], plot[1], label='Spline Fit')
        eval_x = np.linspace(0, summary[0], num=discrete_points)
        plt.scatter(eval_x, summary[1:], marker='+', label='Discrete Points')
        plt.legend(loc='upper left')
        plt.title('Expt. ' + str(idx + 1))
        plt.savefig(write_dir + '/plots' + '/Expt ' + str(idx + 1) + ' _spline' + '.png', bbox_inches='tight')
        plt.close()