Ejemplo n.º 1
0
def step_id(df_f, df_t, forcepla=[2], R='RCAL', L='LCAL', show_msg=True):
    """Identification of step side based on .forces and .trc files.
    """
    if show_msg:
        print('Step identification ... ', end='')
    if not isinstance(forcepla, list):
        forcepla = [forcepla]
    if not forcepla:
        forcepla = list(set([int(fp[-1]) for fp in df_f.columns.values]))
    forces = [
        force + str(fp) for fp in forcepla
        for force in ['FX', 'FY', 'FZ', 'MZ']
    ]
    time = df_f.index.values
    freq = np.round(np.mean(1 / np.diff(time)), 0)
    # resample trc data to the forces frequency
    R = np.interp(time, df_t.index.values, df_t[R].Y.values[:, 0])
    L = np.interp(time, df_t.index.values, df_t[L].Y.values[:, 0])
    # detect onsets in Fy data
    threshold = 50
    n_above = int(0.1 * freq)
    n_below = int(0.01 * freq)
    threshold2 = 10 * threshold  # N
    n_above2 = int(0.02 * freq)
    idx = detect_onset(df_f[forces[1]].values, threshold, n_above, n_below,
                       threshold2, n_above2)
    # column names of the .mot dataframe
    cols = [
        'R_ground_force_vx', 'R_ground_force_vy', 'R_ground_force_vz',
        'R_ground_force_px', 'R_ground_force_py', 'R_ground_force_pz',
        'L_ground_force_vx', 'L_ground_force_vy', 'L_ground_force_vz',
        'L_ground_force_px', 'L_ground_force_py', 'L_ground_force_pz',
        'R_ground_torque_x', 'R_ground_torque_y', 'R_ground_torque_z',
        'L_ground_torque_x', 'L_ground_torque_y', 'L_ground_torque_z'
    ]
    data = np.zeros((df_f.shape[0], len(cols)))
    # step side identification
    for ini, end in idx:
        if R[ini:int((ini + end) / 2)].sum() < L[ini:int((ini + end) /
                                                         2)].sum():
            data[ini:end + 1,
                 [0, 1, 2, 3, 4, 5, 14]] = df_f.values[ini:end + 1, :]
        else:
            data[ini:end + 1,
                 [6, 7, 8, 9, 10, 11, 17]] = df_f.values[ini:end + 1, :]

    df = pd.DataFrame(data=data, columns=cols, index=time)
    df.index.name = 'time'
    if show_msg:
        print('done.')

    return df
def detect_onset_aux(dfData, **args_func_cortes):
    #Si se pasa como argumento corte_ini=1, coge el corte del final de cada ventana
    try:
        from detecta import detect_onset
    except:
        from detect_onset import detect_onset

    try:  #si no se ha indicado el núm corte, coge el primero
        corte_ini = args_func_cortes['corte_ini']
        args_func_cortes.pop('corte_ini', None)
    except:
        corte_ini = 0

    cortes = detect_onset(dfData, **args_func_cortes)

    if corte_ini == 1:
        cortes = cortes[:,
                        corte_ini] + 1  #si se elije el final de la ventana, se añade 1 para que empiece cuando ya ha superado el umbral
        cortes = cortes[:-1]  #quita el último porque suele quedar cortado
    else:
        cortes = cortes[:,
                        corte_ini]  #se queda con el primer o segundo dato de cada par de datos.
        cortes = cortes[1:]  #quita el primero porque suele quedar cortado
    return cortes
Ejemplo n.º 3
0
def filter_forces(df,
                  h,
                  forcepla=[2],
                  fc_forces=20,
                  fc_cop=6,
                  threshold=50,
                  show_msg=True):
    """Filter force data from the treadmill.
    """
    if not isinstance(forcepla, list):
        forcepla = [forcepla]
    if not forcepla:
        forcepla = list(set([int(fp[-1]) for fp in df.columns.values]))
    forces = [
        force + str(fp) for fp in forcepla
        for force in ['FX', 'FY', 'FZ', 'MZ']
    ]
    cops = [cop + str(fp) for fp in forcepla for cop in ['X', 'Z']]

    df2 = df.copy()
    F = df2[forces[1]].values
    freq = h['SampleRate']
    npad = int(freq / 4)
    npad2 = 2

    # filter parameters for COP
    b_cd, a_cd, fc_cd = critic_damp(fcut=fc_cop,
                                    freq=freq,
                                    npass=2,
                                    fcorr=True,
                                    filt='critic')
    if show_msg:
        print('Filtering: COP Fc: {:.2f} Hz'.format(fc_cd), end=', ')

    n_above = int(0.1 * freq)
    n_below = int(0.01 * freq)
    threshold2 = 10 * threshold  # N
    n_above2 = int(0.02 * freq)

    # detect onsets in Fy data
    idx1 = detect_onset(F, threshold, n_above, n_below, threshold2, n_above2)
    for cop in cops:
        COP = df2[cop].values
        # for each foot strike
        for ini, end in idx1:
            # reliable COP portion
            idx2 = detect_onset(F[ini:end + 1],
                                4 * threshold,
                                n_above,
                                n_below,
                                None,
                                1,
                                del_ini_end=False)
            if idx2.shape[0]:
                # fit polynomiun
                y = COP[ini + idx2[0, 0]:ini + idx2[0, 1] + 1]
                t = ini + idx2[0, 0] + np.linspace(0, y.shape[0] - 1,
                                                   y.shape[0])
                p = np.polyfit(t, y, 2)
                # values at the extremities for using to pad data
                z = np.polyval(p, [ini, end])
                q = np.hstack((z[0] * np.ones(npad), COP[ini:end + 1],
                               z[1] * np.ones(npad)))
                # filter data
                q2 = signal.filtfilt(b_cd, a_cd, q)

                COP[ini - npad2:end + 1 + npad2] = q2[npad - npad2:-npad +
                                                      npad2]

        df2[cop] = COP

    b_cd, a_cd, fc_cd = critic_damp(fcut=fc_forces,
                                    freq=freq,
                                    npass=2,
                                    fcorr=True,
                                    filt='critic')
    if show_msg:
        print('Forces Fc: {:.2f} Hz'.format(fc_cd))
    for force in forces:
        df2[force] = signal.filtfilt(b_cd, a_cd, df2[force])

    return df2