def _leg2d(self, time, marker_pos, normalized_force_plate_values, cutoff, sample_rate): """This method effectively does the same thing that the Octave routine does.""" # differentiate to get the marker velocities and accelerations marker_vel = process.derivative(time, marker_pos, method='combination') marker_acc = process.derivative(time, marker_vel, method='combination') # filter all the input data with the same filter marker_pos = process.butterworth(marker_pos, cutoff, sample_rate, axis=0) marker_vel = process.butterworth(marker_vel, cutoff, sample_rate, axis=0) marker_acc = process.butterworth(marker_acc, cutoff, sample_rate, axis=0) force_array = process.butterworth(normalized_force_plate_values, cutoff, sample_rate, axis=0) # compute the inverse dynamics inv_dyn = lower_extremity_2d_inverse_dynamics dynamics = inv_dyn(time, marker_pos, marker_vel, marker_acc, force_array) return dynamics
def time_derivative(self, col_names, new_col_names=None): """Numerically differentiates the specified columns with respect to the time index and adds the new columns to `self.data`. Parameters ========== col_names : list of strings The column names for the time series which should be numerically time differentiated. new_col_names : list of strings, optional The desired new column name(s) for the time differentiated series. If None, then a default name of `Time derivative of <origin column name>` will be used. """ if new_col_names is None: new_col_names = ['Time derivative of {}'.format(c) for c in col_names] for col_name, new_col_name in zip(col_names, new_col_names): self.data[new_col_name] = \ process.derivative(self.data.index.values.astype(float), self.data[col_name].values, method='combination')
def find_constant_speed(time, speed, plot=False, filter_cutoff=1.0): """Returns the indice at which the treadmill speed becomes constant and the time series when the treadmill speed is constant. Parameters ========== time : array_like, shape(n,) A monotonically increasing array. speed : array_like, shape(n,) A speed array, one sample for each time. Should ramp up and then stablize at a speed. plot : boolean, optional If true a plot will be displayed with the results. filter_cutoff : float, optional The filter cutoff frequency for filtering the speed in Hertz. Returns ======= indice : integer The indice at which the speed is consider constant thereafter. new_time : ndarray, shape(n-indice,) The new time array for the constant speed section. """ sample_rate = 1.0 / (time[1] - time[0]) filtered_speed = process.butterworth(speed, filter_cutoff, sample_rate) acceleration = process.derivative(time, filtered_speed, method='central', padding='second order') last = acceleration[int(0.2 * len(acceleration)):] noise_level = np.max(np.abs(last - np.mean(last))) reversed_acceleration = acceleration[::-1] indice = np.argmax(reversed_acceleration > noise_level) additional_samples = sample_rate * 0.65 new_indice = indice - int(round(additional_samples)) if plot is True: fig, ax = plt.subplots(2, 1) ax[0].plot(time, speed, '.', time, filtered_speed, 'g-') ax[0].plot( np.ones(2) * (time[len(time) - new_indice]), np.hstack((np.max(speed), np.min(speed)))) ax[1].plot(time, acceleration, '.') fig.show() return len(time) - (new_indice), time[len(time) - new_indice]
def find_constant_speed(time, speed, plot=False, filter_cutoff=1.0): """Returns the indice at which the treadmill speed becomes constant and the time series when the treadmill speed is constant. Parameters ========== time : array_like, shape(n,) A monotonically increasing array. speed : array_like, shape(n,) A speed array, one sample for each time. Should ramp up and then stablize at a speed. plot : boolean, optional If true a plot will be displayed with the results. filter_cutoff : float, optional The filter cutoff frequency for filtering the speed in Hertz. Returns ======= indice : integer The indice at which the speed is consider constant thereafter. new_time : ndarray, shape(n-indice,) The new time array for the constant speed section. """ sample_rate = 1.0 / (time[1] - time[0]) filtered_speed = process.butterworth(speed, filter_cutoff, sample_rate) acceleration = process.derivative(time, filtered_speed, method='central', padding='second order') last = acceleration[int(0.2 * len(acceleration)):] noise_level = np.max(np.abs(last - np.mean(last))) reversed_acceleration = acceleration[::-1] indice = np.argmax(reversed_acceleration > noise_level) additional_samples = sample_rate * 0.65 new_indice = indice - additional_samples if plot is True: fig, ax = plt.subplots(2, 1) ax[0].plot(time, speed, '.', time, filtered_speed, 'g-') ax[0].plot(np.ones(2) * (time[len(time) - new_indice]), np.hstack((np.max(speed), np.min(speed)))) ax[1].plot(time, acceleration, '.') fig.show() return len(time) - (new_indice), time[len(time) - new_indice]
def peak_detection(x): dx = process.derivative(time, x, method="combination") dx[dx > 0] = 1 dx[dx < 0] = -1 ddx = process.derivative(time, dx, method="combination") peaks = [] for i, spike in enumerate(ddx < 0): if spike == True: peaks.append(i) peaks = peaks[::2] threshold_value = (max(x) - min(x))*threshold + min(x) peak_indices = [] for i in peaks: if x[i] > threshold_value: peak_indices.append(i) return peak_indices
import simulation from grf_landmark_settings import settings # load the data and find a controller trial_number = '068' trial = utils.Trial(trial_number) trial._write_event_data_frame_to_disk('Longitudinal Perturbation') event_data_frame = trial.event_data_frames['Longitudinal Perturbation'] event_data_frame = simulation.estimate_trunk_somersault_angle(event_data_frame) # TODO : will likely need to low pass filter the two time derivatives event_data_frame['Trunk.Somersault.Rate'] = \ process.derivative(event_data_frame.index.values.astype(float), event_data_frame['Trunk.Somersault.Angle'], method='combination') event_data_frame['RGTRO.VelY'] = \ process.derivative(event_data_frame.index.values.astype(float), event_data_frame['RGTRO.PosY'], method='combination') # TODO : Ensure that the modified data frame is infact the one in the Trial # object. trial._write_inverse_dynamics_to_disk('Longitudinal Perturbation', force=True) trial._section_into_gait_cycles('Longitudinal Perturbation', force=True) gait_data = trial.gait_data_objs['Longitudinal Perturbation'] sensor_labels, control_labels, result, solver = \ trial.identification_results('Longitudinal Perturbation', 'joint isolated')