def __init__(self, biplane_marker_data: ViconAccuracyMarkerData, vicon_endpts: np.ndarray, f_t_v: np.ndarray, c3d_data_labeled: np.ndarray, c3d_data_filled: np.ndarray, marker_except: Dict[str, Any], dt: float, use_filled_portion=True): super().__init__(biplane_marker_data, vicon_endpts, f_t_v, c3d_data_labeled) self.use_filled_portion = use_filled_portion # smooth _, _, _, smoothed = \ piecewise_filter_with_exception(marker_except, c3d_data_labeled, c3d_data_filled, dt) # now make sure that the smoothed data extends from vicon_endpts[0] to vicon_endpts[1] smoothed_rectified = np.full((vicon_endpts[1] - vicon_endpts[0], 3), np.nan) source_start_idx = vicon_endpts[0] - smoothed.endpts[ 0] if smoothed.endpts[0] < vicon_endpts[0] else 0 source_stop_idx = vicon_endpts[1] - smoothed.endpts[0] if smoothed.endpts[1] > vicon_endpts[1] \ else smoothed.endpts[1] - smoothed.endpts[0] target_start_idx = smoothed.endpts[0] - vicon_endpts[ 0] if smoothed.endpts[0] > vicon_endpts[0] else 0 target_stop_idx = target_start_idx + (source_stop_idx - source_start_idx) smoothed_rectified[target_start_idx:target_stop_idx, :] = \ smoothed.means.pos[source_start_idx:source_stop_idx, :] # transform the vicon marker data into the fluoro CS self.smoothed_vmd_fluoro = vec_transform( f_t_v, make_vec_hom(smoothed_rectified))[:, :3]
def trial_exporter(trial, marker_names, filling_directives_all, dt, subject_folder): log.info('Exporting trial %s', trial.trial_name) markers_to_fill = trial_filling_directives(filling_directives_all, trial.trial_name) smooth_marker_pos = np.stack( [trial.smoothed[marker_name] for marker_name in marker_names], 0) sfs_marker_pos = smooth_marker_pos.copy() # fill then smooth again for (marker_name, fill_from) in markers_to_fill.items(): assert (marker_name not in fill_from) marker_idx = marker_names.index(marker_name) filled_marker, _ = fill_gaps_rb( trial.smoothed[marker_name], np.stack( [trial.smoothed[fill_source] for fill_source in fill_from], 0)) # smooth _, _, _, smoothed = piecewise_filter_with_exception( {}, filled_marker, filled_marker, dt, white_noise_var=100000) sfs_data = np.full_like(filled_marker, np.nan) sfs_data[ smoothed.endpts[0]:smoothed.endpts[1], :] = smoothed.means.pos sfs_marker_pos[marker_idx] = sfs_data def process_trial(static_markers, tracking_markers): torso_traj = compute_trajectory_continuous(static_markers, tracking_markers) torso_pos = torso_traj[:, :3, 3] torso_quat = quaternion.as_float_array( quaternion.from_rotation_matrix(torso_traj[:, :3, :3], nonorthogonal=False)) return torso_pos, torso_quat stat_markers = trial.subject.torso.static_markers_intrinsic torso_pos_sfs, torso_quat_sfs = process_trial(stat_markers, sfs_marker_pos) def export_to_csv(file_name, export_data): header_line = 'pos_x, pos_y, pos_z, quat_w, quat_x, quat_y, quat_z' np.savetxt(file_name, np.concatenate(export_data, axis=1), delimiter=',', fmt='%.11g', comments='', header=header_line) trial_folder = subject_folder / trial.trial_name trial_folder.mkdir(parents=True, exist_ok=True) trial_file = trial_folder / (trial.trial_name + '_torso.csv') export_to_csv(trial_file, [torso_pos_sfs, torso_quat_sfs])
def marker_plotter(trial: ViconCsvTrial, marker_name: str, marker_except: Dict[str, Any], dt: float, plotter_cls: Type, subj_dir: Union[Path, None] = None) -> None: """Plot the specified marker (marker_name) specified in trial using the plotter specified by plotter_cls.""" raw, filled, filtered, smoothed = \ piecewise_filter_with_exception(marker_except, trial.labeled[marker_name], trial.filled[marker_name], dt) plotter = plotter_cls(trial.trial_name, marker_name, raw, filled, filtered, smoothed, trial.vicon_endpts) figs = plotter.plot() plt.show() if subj_dir: trial_dir = subj_dir / trial.trial_name trial_dir.mkdir(parents=True, exist_ok=True) figs_to_pdf(figs, trial_dir, marker_name)
def trial_plotter(trial: ViconCsvTrial, dt: float, subj_dir: Path, all_smoothing_except: Dict[str, Any]) -> None: """Smooth all the markers in the supplied trial then create a PDF record for each marker, and a summary PDF record for the trial.""" log.info('Smoothing trial %s', trial.trial_name) trial_dir = subj_dir / trial.trial_name trial_dir.mkdir(parents=True, exist_ok=True) trial_pdf_file = subj_dir / (trial.trial_name + '.pdf') # trial summary PDF with PdfPages(trial_pdf_file) as trial_pdf: for marker in MARKERS: if marker in trial.vicon_csv_data_labeled.columns: log.info('Smoothing marker %s', marker) marker_pdf_file = trial_dir / (marker + '.pdf') try: marker_exceptions = marker_smoothing_exceptions( all_smoothing_except, trial.trial_name, marker) raw, filled, filtered, smoothed = \ piecewise_filter_with_exception(marker_exceptions, trial.labeled[marker], trial.filled[marker], dt) except InsufficientDataError as e: create_and_save_error_figure(marker + ' Insufficient Data', trial_pdf) log.warning( 'Skipping marker {} for trial {} because: {}'.format( marker, trial.trial_name, e)) continue except DoNotUseMarkerError as e: create_and_save_error_figure(marker + ' SHOULD NOT USE', trial_pdf) log.warning( 'Skipping marker {} for trial {} because: {}'.format( marker, trial.trial_name, e)) continue marker_plotter = SmoothingOutputPlotter( trial.trial_name, marker, raw, filled, filtered, smoothed, trial.vicon_endpts) figs = marker_plotter.plot() # marker PDF with PdfPages(marker_pdf_file) as marker_pdf: for (fig_num, fig) in enumerate(figs): marker_pdf.savefig(fig) if fig_num in [0, 1]: trial_pdf.savefig(fig) fig.clf() plt.close(fig) else: log.warning('Marker %s missing', marker) create_and_save_error_figure(marker, trial_pdf)
def trial_exporter(trial: ViconCsvTrial, dt: float, subj_dir: Path, all_smoothing_except: Dict[str, Any]) -> None: """Smooth all markers in trial and export to CSV.""" log.info('Exporting trial %s', trial.trial_name) trial_dir = subj_dir / trial.trial_name trial_dir.mkdir(parents=True, exist_ok=True) data_to_export = [] marker_names = [] for marker in MARKERS: if marker in trial.vicon_csv_data_labeled.columns: log.info('Smoothing marker %s', marker) try: marker_exceptions = marker_smoothing_exceptions( all_smoothing_except, trial.trial_name, marker) raw, _, _, smoothed = \ piecewise_filter_with_exception(marker_exceptions, trial.labeled[marker], trial.filled[marker], dt) except InsufficientDataError as e: log.warning( 'Skipping marker {} for trial {} because: {}'.format( marker, trial.trial_name, e)) continue except DoNotUseMarkerError as e: log.warning( 'Skipping marker {} for trial {} because: {}'.format( marker, trial.trial_name, e)) continue marker_export_data = np.full((raw.endpts[1], 3), np.nan) marker_export_data[ smoothed.endpts[0]:smoothed.endpts[1], :] = smoothed.means.pos data_to_export.append(marker_export_data) marker_names.append(marker) else: log.warning('Marker %s missing', marker) export_to_csv(trial_dir / (trial.trial_name + '_vicon_smoothed.csv'), data_to_export, marker_names)
def trial_plotter(trial, marker_nms, filling_direct_all): log.info('Processing trial %s', trial.trial_name) markers_to_fill = trial_filling_directives(filling_direct_all, trial.trial_name) gaps_filled = {} filled_data = {} sfs_data = {} if not markers_to_fill: return None for (marker_name, fill_from) in markers_to_fill.items(): assert (marker_name not in fill_from) filled_marker, gaps = fill_gaps_rb( trial.smoothed[marker_name], np.stack( [trial.smoothed[fill_source] for fill_source in fill_from], 0)) gaps_filled[marker_name] = gaps _, _, _, smoothed = piecewise_filter_with_exception( {}, filled_marker, filled_marker, db.attrs['dt'], white_noise_var=100000) filled_data[marker_name] = filled_marker sfs_data[marker_name] = np.full_like(filled_marker, np.nan) sfs_data[marker_name][ smoothed.endpts[0]:smoothed.endpts[1], :] = smoothed.means.pos smooth_marker_data = np.stack( [trial.smoothed[marker_name] for marker_name in marker_nms], 0) return MarkerClusterFillPlotter(trial.trial_name, smooth_marker_data, marker_names, gaps_filled, markers_to_fill, filled_data, sfs_data, trial.vicon_endpts)
def trial_plotter(trial, marker_names, filling_directives_all, dt): log.info('Processing trial %s', trial.trial_name) markers_to_fill = trial_filling_directives(filling_directives_all, trial.trial_name) smooth_marker_pos = np.stack( [trial.smoothed[marker_name] for marker_name in marker_names], 0) prev_filled_marker_pos = np.stack( [trial.filled[marker_name] for marker_name in marker_names], 0) filled_marker_pos = smooth_marker_pos.copy() sfs_marker_pos = smooth_marker_pos.copy() # fill then smooth again for (marker_name, fill_from) in markers_to_fill.items(): assert (marker_name not in fill_from) marker_idx = marker_names.index(marker_name) filled_marker, _ = fill_gaps_rb( trial.smoothed[marker_name], np.stack( [trial.smoothed[fill_source] for fill_source in fill_from], 0)) filled_marker_pos[marker_idx] = filled_marker # smooth _, _, _, smoothed = piecewise_filter_with_exception( {}, filled_marker, filled_marker, dt, white_noise_var=100000) sfs_data = np.full_like(filled_marker, np.nan) sfs_data[ smoothed.endpts[0]:smoothed.endpts[1], :] = smoothed.means.pos sfs_marker_pos[marker_idx] = sfs_data def process_trial(static_markers, tracking_markers, traj_func, base_frame_inv=None): torso_traj = traj_func(static_markers, tracking_markers) present_frames = np.nonzero(~np.any(np.isnan(torso_traj), (-2, -1)))[0] if present_frames.size == 0: num_frames = tracking_markers.shape[1] torso_pos = np.full((num_frames, 3), np.nan) torso_eul = np.full((num_frames, 3), np.nan) base_frame_inv = None else: if base_frame_inv is None: base_frame_inv = ht_inv(torso_traj[present_frames[0]]) torso_intrinsic = change_cs(base_frame_inv, torso_traj) torso_pos = torso_intrinsic[:, :3, 3] torso_eul = np.rad2deg(zxy_intrinsic(torso_intrinsic)) return (torso_pos, torso_eul), base_frame_inv stat_markers = trial.subject.torso.static_markers_intrinsic torso_kine_smooth, base_inv = process_trial(stat_markers, smooth_marker_pos, compute_trajectory) torso_kine_sfs, _ = process_trial(stat_markers, sfs_marker_pos, compute_trajectory_continuous, base_inv) torso_kine_filled, _ = process_trial(stat_markers, filled_marker_pos, compute_trajectory_continuous, base_inv) torso_kine_prev_filled, _ = process_trial(stat_markers, prev_filled_marker_pos, compute_trajectory, base_inv) return TorsoTrajComparisonPlotter(trial.trial_name, torso_kine_prev_filled, torso_kine_smooth, torso_kine_filled, torso_kine_sfs, trial.vicon_endpts)