27-12-2020 GC
from math import log10
from pathlib import Path
import pandas as pd
def read_BC_direct():
f_in = '/media/guido/LACIE/Cingle_Guido/Master/BC_direct_thresholds.xlsx'
p_in = Path(f_in)
df = pd.read_excel(p_in, sheet_name=0, header=0, nrows=85)
df = df.drop(['Unnamed: 0'], axis=1)
type_dict = {'Study_ID': 'int', 'Device': 'str',
'BCd_250':'float32', 'BCd_250':'float32', 'BCd_500':'float32',
'BCd_1000': 'float32', 'BCd_1500': 'float32', 'BCd_2000': 'float32', 'BCd_3000': 'float32',
'BCd_4000': 'float32'}
df = df.astype(type_dict)
df = df.fillna(pd.NA)
return df
def BAHA5P_forcelevels(df):
idx = df.columns[2:]
RETFL = [57.7, 52.7, 39.6, 37.0, 28.9, 31.6, 32.1]
reference_force_levels = pd.Series(data=RETFL, index=idx, dtype='float32')
return reference_force_levels
def BP110_forcelevels(df):
idx = df.columns[2:]
RETFL = [61.0, 53.9, 39.4, 38.0, 31.0, 32.0, 32.1]
reference_force_levels = pd.Series(data=RETFL, index=idx, dtype='float32')
return reference_force_levels
def correction_RETFL(df, device):
device_grouped = df.groupby('Device') # make group object dependent on device type
grouped = device_grouped.get_group(device) # make data frame device specific
info = grouped[['Study_ID', 'Device']] # select columns 0 and 1
grouped = grouped.drop(columns=['Study_ID', 'Device']) # drop columns 0 and 1
corrected = grouped.add(RETFL_specific(df, device), axis = 1) # add Series with RETFL values = thresholds FL
corrected = pd.concat([info, corrected], axis=1) # add newly columns 0 and 1
return corrected
def RETFL_specific(df, device):
if device == 'BAHA5P': return BAHA5P_forcelevels(df)
if device == 'BP110': return BP110_forcelevels(df)
def log_f_third():
frequencies = [250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000, 6300, 8000]
f = pd.Series(frequencies, dtype = 'int16') # array with 1/3 octave band CF
f_log_third_bands = f.apply(log10) # log version of the same array
return f_log_third_bands
def combination_BCD():
thresholds = read_BC_direct() # read xlsx with BC direct thresholds
thresholds_fl_BP110 = correction_RETFL(thresholds, 'BP110') # thresholds in FL for BP110 patients
thresholds_fl_BAHA5P = correction_RETFL(thresholds, 'BAHA5P') # thresholds in FL for BAHA5P patients
thresholds_fl = pd.concat([thresholds_fl_BP110,
thresholds_fl_BAHA5P], axis=0) # concatenation of device spec. df
return thresholds_fl
def write_res_in_master(df):
# write results to xlsx file in Master directory
fout = '/media/guido/LACIE/Cingle_Guido/Master/BC_dir_thr_third.xlsx'
pout = Path(fout)
with pd.ExcelWriter(pout) as writer:
df.to_excel(writer, sheet_name='BC_dir_thr_third')
# interpolation of threshold, to calculate thresholds for 1/3 octave bands
a = [0, 1, 2, 5, 8, 11, 14, 15, 16, 17] # lists of relevant indeces
b = [0, 1, 2, 3, 4, 6, 8, 8, 8, 8]
frequencies = [250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000, 6300, 8000]
idx_interpol = [n for n in range(18)] # preparation empty dataframe
interpolated = pd.DataFrame()
flog = log_f_third()
tfl = combination_BCD()
for i in range(len(tfl.index)):
thr = pd.Series(tfl.iloc[i])
interpol = pd.Series(index=idx_interpol, dtype='float64')
for j in range(len(a)): interpol[a] = thr[b] # thresholds for octave bands
interpol[3] = thr[2] + (thr[3] - thr[2]) * (flog[1] - flog[0]) / (flog[3] - flog[0]) # 315 Hz
interpol[4] = thr[2] + (thr[3] - thr[2]) * (flog[2] - flog[0]) / (flog[3] - flog[0]) # 400 Hz
interpol[6] = thr[3] + (thr[4] - thr[3]) * (flog[4] - flog[3]) / (flog[6] - flog[3]) # 630 Hz
interpol[7] = thr[3] + (thr[4] - thr[3]) * (flog[5] - flog[3]) / (flog[6] - flog[3]) # 800 Hz
interpol[9] = thr[4] + (thr[5] - thr[4]) * (flog[7] - flog[6]) / (log10(1500) - flog[6]) # 1250 Hz
interpol[10] = thr[5] + (thr[6]- thr[5]) * (flog[8] - log10(1500)) / (flog[9] - log10(1500)) #1.6kHz
interpol[12] = thr[6] + (thr[7]- thr[6]) * (flog[10] - flog[9]) / (log10(3000)- flog[9]) #2.5kHz
interpol[13] = thr[7] + (thr[8]- thr[7]) * (flog[11] - log10(3000)) / (flog[12]-log10(3000)) #3.15kHz
interpolated = pd.concat([interpolated, interpol], axis = 1) # concatenation of lines with data
interpolated = interpolated.T
interpolated = interpolated.reset_index()
interpolated = interpolated.drop(columns=['index'])
f_names = [str(f) + '_Hz' for f in frequencies]
name_columns = ['Study_ID', 'Device'] + f_names
f_dict=dict()
for i in range(len(f_names)): f_dict.update({f_names[i]:'int32'})
interpolated.columns = name_columns
interpolated = interpolated.fillna(-999)
interpolated = interpolated.round(0)
interpolated = interpolated.astype(f_dict)
interpolated = interpolated.replace(-999, pd.NA)
interpolated
Study_ID | Device | 250_Hz | 315_Hz | 400_Hz | 500_Hz | 630_Hz | 800_Hz | 1000_Hz | 1250_Hz | 1600_Hz | 2000_Hz | 2500_Hz | 3150_Hz | 4000_Hz | 5000_Hz | 6300_Hz | 8000_Hz | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | BP110 | 86 | 87 | 88 | 89 | 84 | 79 | 74 | 76 | 78 | 76 | 74 | 71 | 67 | 67 | 67 | 67 |
1 | 2 | BP110 | 86 | 87 | 88 | 89 | 82 | 76 | 69 | 58 | 51 | 61 | 73 | 85 | 102 | 102 | 102 | 102 |
2 | 3 | BP110 | 91 | 92 | 93 | 94 | 82 | 71 | 59 | <NA> | <NA> | 56 | 68 | 81 | 102 | 102 | 102 | 102 |
3 | 4 | BP110 | 81 | 79 | 76 | 74 | 69 | 64 | 59 | <NA> | <NA> | 61 | <NA> | <NA> | 72 | 72 | 72 | 72 |
4 | 5 | BP110 | 76 | 72 | 68 | 64 | 59 | 54 | 49 | <NA> | <NA> | 51 | <NA> | <NA> | 57 | 57 | 57 | 57 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
80 | 81 | BAHA5P | 88 | 91 | 94 | 98 | 85 | 72 | 60 | 69 | 74 | 64 | 60 | 60 | 77 | 77 | 77 | 77 |
81 | 82 | BAHA5P | 78 | 83 | 88 | 93 | 85 | 77 | 70 | 68 | 64 | 54 | 61 | 68 | 77 | 77 | 77 | 77 |
82 | 83 | BAHA5P | 83 | 81 | 79 | 78 | 73 | 69 | 65 | 52 | 42 | 44 | 56 | 69 | 82 | 82 | 82 | 82 |
83 | 84 | BAHA5P | 88 | 91 | 94 | 98 | 85 | 72 | 60 | 66 | 74 | 79 | 89 | 96 | 92 | 92 | 92 | 92 |
84 | 85 | BAHA5P | 88 | 88 | 88 | 88 | 82 | 75 | 70 | 71 | 69 | 59 | 52 | 50 | 67 | 67 | 67 | 67 |
85 rows × 18 columns
interpolated.set_index('Study_ID', inplace=True, verify_integrity=True)
interpolated.sort_index(inplace=True)
interpolated.reset_index(inplace=True)
interpolated
Study_ID | Device | 250_Hz | 315_Hz | 400_Hz | 500_Hz | 630_Hz | 800_Hz | 1000_Hz | 1250_Hz | 1600_Hz | 2000_Hz | 2500_Hz | 3150_Hz | 4000_Hz | 5000_Hz | 6300_Hz | 8000_Hz | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | BP110 | 86 | 87 | 88 | 89 | 84 | 79 | 74 | 76 | 78 | 76 | 74 | 71 | 67 | 67 | 67 | 67 |
1 | 2 | BP110 | 86 | 87 | 88 | 89 | 82 | 76 | 69 | 58 | 51 | 61 | 73 | 85 | 102 | 102 | 102 | 102 |
2 | 3 | BP110 | 91 | 92 | 93 | 94 | 82 | 71 | 59 | <NA> | <NA> | 56 | 68 | 81 | 102 | 102 | 102 | 102 |
3 | 4 | BP110 | 81 | 79 | 76 | 74 | 69 | 64 | 59 | <NA> | <NA> | 61 | <NA> | <NA> | 72 | 72 | 72 | 72 |
4 | 5 | BP110 | 76 | 72 | 68 | 64 | 59 | 54 | 49 | <NA> | <NA> | 51 | <NA> | <NA> | 57 | 57 | 57 | 57 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
80 | 81 | BAHA5P | 88 | 91 | 94 | 98 | 85 | 72 | 60 | 69 | 74 | 64 | 60 | 60 | 77 | 77 | 77 | 77 |
81 | 82 | BAHA5P | 78 | 83 | 88 | 93 | 85 | 77 | 70 | 68 | 64 | 54 | 61 | 68 | 77 | 77 | 77 | 77 |
82 | 83 | BAHA5P | 83 | 81 | 79 | 78 | 73 | 69 | 65 | 52 | 42 | 44 | 56 | 69 | 82 | 82 | 82 | 82 |
83 | 84 | BAHA5P | 88 | 91 | 94 | 98 | 85 | 72 | 60 | 66 | 74 | 79 | 89 | 96 | 92 | 92 | 92 | 92 |
84 | 85 | BAHA5P | 88 | 88 | 88 | 88 | 82 | 75 | 70 | 71 | 69 | 59 | 52 | 50 | 67 | 67 | 67 | 67 |
85 rows × 18 columns
write_res_in_master(interpolated)