<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># some basic functions  used frequently 

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, filtfilt
import csv


# plot data
def plot_data(figure_num, x_data, y_data,data_marker, x_label, y_label, test_num): 
    plt.figure(figure_num)
    plt.plot(x_data, y_data, data_marker, label = ('test' + str(test_num)))
    plt.legend(loc = 2)
    plt.legend(loc = 2)
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    
    
# find index of nearest value 
def find_nearest(array, value):
        array = np.asarray(array)
        idx = (np.abs(array - value)).argmin()
        return  idx


# stress calculation 
def calculate_stress(area_cross_section, load):
    stress = [c / float(area_cross_section) for c in load]
    stress = [c * 0.0098 for c in stress]     # gf to N
    return stress


# strain calculation
def calculate_strain(dimensions, disp):
    strain = [c / float(dimensions) for c in disp]
    return strain
    
# modulus calculation
def modulus(strain,stress):
    (mod_fit,inter) = np.polyfit(strain,stress)
    return mod_fit
    
 
# save data to text file
def save_extracted_data(outputfile_name, *args): 
    fd_data = np.array(*args)
    fd_data = fd_data.T
    datafile_id = open(outputfile_name + '.txt', 'w+')
    np.savetxt(datafile_id, fd_data)
    datafile_id.close()
 

# third order butterworth filter 
def butter_lowpass(cutoff, fs, order):
         nyq = 0.5 * fs
         normal_cutoff = cutoff / nyq
         b, a = butter(order, normal_cutoff, btype = 'low', analog = False)
         return b, a

def butter_lowpass_filter(data, cutoff, fs, order):
         b, a = butter_lowpass(cutoff, fs, order = order)
#         y = lfilter(b, a, data)
         y = filtfilt(b, a, data,method = "gust")
         return y


# mean and SD
 



# coeff of variation
def cov(std_dev,mean):
    cov = (std_dev/mean) * 100
    return cov
    
# extract csv information to dictionary 
def extract_to_dict(output_file_name):
    f_output = output_file_name
    with open(f_output, mode='r') as f_output:
       reader = csv.reader(f_output)
       mydict = dict(reader)
       return mydict


# calculate area under the curve
def area(y_array, x_array):
    area = np.trapz(y_array,x_array)
    return area
    

# Neo-Hookean model in terms of stretch and stress

def fitfunc_NeoHookean(C10,x):
    W = C10 * (x - np.power(x,-2)) # Target function, Neo-Hookean, uniaxial loading
    return W 
    
    

# Mooney-Rivlin model in terms of stretch and stress

def fitfunc_Mooney_Rivlin(C, x):
    W = ((2 * C[0]) + (2 * C[1] * np.power(x,-1))) * (x - np.power(x,-2)) # Target function, Mooney-Rivlin, uniaxial loading
    return W 
    
# normalize load disp
    
def norml_load_before_pc(disp, load, norm_pnt_pc,load_ref):
    # normalizing disp
    disp = [ x - float(norm_pnt_pc) for x in disp]  
     # find actual 10g location
    idx = find_nearest(load, load_ref)
    disp = [x - disp[idx] for x in disp]  
    # clip all data before 10g force location  
    idx1 = find_nearest(disp, 0.0) 
    disp = disp[idx1:]
    load = load[idx1:]   
    # adjust loads to 0 
    load = [x - load[0] for x in load]
    return disp, load , idx
    
def norml_unload_before_pc(disp, load, norm_pnt_pc, id):
    # normalizing disp
    disp = [ x - float(norm_pnt_pc) for x in disp]  
     # find actual 10g location
#    idx = find_nearest(load, 2)
    disp = [x - disp[id] for x in disp]  
    # clip all data before 10g force location  
    idx = find_nearest(disp, 0.0) 
    disp = disp[:idx]
    load = load[:idx]   
    # adjust loads to 0 
    load = [x - load[0] for x in load]
    return disp, load


def norml_load_after_pc(disp, load, norm_pnt_pc,load_ref,id): # using 10g location from the first loading ramp as reference
    # normalizing disp
    disp = [ x - float(norm_pnt_pc) for x in disp]  
     # find actual 10g location
#    idx = find_nearest(load, load_ref)
    disp = [x - disp[id] for x in disp]  
    # clip all data before 10g force location  
    idx1 = find_nearest(disp, 0.0) 
    disp = disp[idx1:]
    load = load[idx1:]   
    # adjust loads to 0 
    load = [x - load[0] for x in load]
    return disp, load , idx1</pre></body></html>