def __call__(self, x): return PchipInterpolator.__call__(self, x, 1)
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()