This documentation provides an overview of the high-level workflow involved in processing
single-camera datasets using singlecam_example.py
. singlecam_example.py
is currently the most
up-to-date script, incorporating efficient optimization routines for finding a suitable smoothing
parameter given data, and is the most useful script to walk through in order to provide a high-level
understanding of the EKS workflow.
Here, we will progress through the high-level workflow of singlecam_example.py
. Further details on
key functions ensemble_kalman_smoother_singlecam
and singlecam_optimize_smooth
are provided as
well.
The singlecam_example.py
script demonstrates how to process and smooth single-camera datasets.
It includes steps to handle input/output operations, format data, and apply the Ensemble Kalman
Smoother (EKS).
-
Collect User-Provided Arguments:
- Define the
smoother_type
as 'singlecam'. - Parse command-line arguments using
handle_parse_args(smoother_type)
. - Extract and set various input parameters such as
input_dir
,data_type
,save_dir
, save_filename
,bodypart_list
,s
,s_frames
, andblocks
.
- Define the
-
Load and Format Input Data:
- Use
format_data
to read and format input files, and prepare an empty DataFrame for output. - If
bodypart_list
is not provided, use keypoint names from the input data. - Print the keypoints being processed.
- Use
-
Convert Input Data to 3D Array:
- Convert the list of DataFrames to a 3D NumPy array using
np.stack
. - Map keypoint names to their respective indices in the DataFrames.
- Crop the 3D array to include only the columns corresponding to the specified body parts
- (
_x
,_y
,_likelihood
).
- Convert the list of DataFrames to a 3D NumPy array using
-
Apply Ensemble Kalman Smoother:
- Call
ensemble_kalman_smoother_singlecam
fromsinglecam_smoother.py
with the prepared 3D array and other arguments to obtain smoothed results (df_dicts
,s_finals
).
- Call
-
Save Smoothed Results:
- For each body part, convert the resulting DataFrames to CSV files.
- Use
populate_output_dataframe
to integrate the results into the output DataFrame. - Save the output DataFrame as a CSV file in the specified directory.
-
Plot Results:
- Use
plot_results
to visualize the smoothed data. - Plot the results for a specific keypoint (
keypoint_i
).
- Use
(from eks/singlecam_smoother.py
)
This function performs Ensemble Kalman Smoothing on 3D marker data from a single camera. It takes as input a 3D array of marker data, a list of body parts, smoothing parameters, and frames, and returns dataframes with smoothed predictions, final smoothing parameters, and Negative Log-Likelihood (NLL) values.
markers_3d_array
(np.ndarray): A 3D array of marker data with dimensions corresponding to time frames, body parts, and coordinates (x, y, z).bodypart_list
(list): A list of body parts for which the data is being processed.smooth_param
(float): A parameter controlling the smoothing process.s_frames
(list): A list of frames used in the smoothing process.blocks
(list): Optional. A list of blocks for segmenting the data (default is an empty list).ensembling_mode
(str): The mode used for ensembling the data (default is 'median').zscore_threshold
(float): The Z-score threshold for outlier detection (default is 2).
tuple
: A tuple containing:- Dataframes with smoothed predictions.
- Final smoothing parameters (per keypoint).
- NLL values (used for finding the ideal smoothing parameter value)
-
Initialization:
- Extract the total number of frames (
T
) and the number of keypoints (n_keypoints
) from themarkers_3d_array
. - Define the number of coordinates (
n_coords
) as 2 (x and y).
- Extract the total number of frames (
-
Ensemble Statistics:
- Compute ensemble statistics by calling
jax_ensemble
with the marker data and ensembling mode. - Extract ensemble predictions (
ensemble_preds
), variances (ensemble_vars
), and average keypoints (keypoints_avg_dict
).
- Compute ensemble statistics by calling
-
Adjust Observations:
- Calculate mean and adjusted observations by calling
adjust_observations
with the average keypoints, number of keypoints, and ensemble predictions. - Obtain
mean_obs_dict
,adjusted_obs_dict
, andscaled_ensemble_preds
.
- Calculate mean and adjusted observations by calling
-
Initialize Kalman Filter:
- Initialize Kalman filter values by calling
initialize_kalman_filter
with the scaled ensemble predictions, adjusted observations, and number of keypoints. - Obtain initial means (
m0s
), covariances (S0s
), state transition matrices (As
), covariance matrices (cov_mats
), observation matrices (Cs
), observation covariances (Rs
), and observations (ys
).
- Initialize Kalman filter values by calling
-
Smoothing:
- Perform the main smoothing function by calling
singlecam_optimize_smooth
with the initialized values, ensemble variances, frames, smoothing parameter, and blocks. - Obtain final smoothing parameters (
s_finals
), means (ms
), and covariances (Vs
).
- Perform the main smoothing function by calling
-
Process Each Keypoint:
- Initialize arrays for smoothed means (
y_m_smooths
), variances (y_v_smooths
), and predicted arrays (eks_preds_array
). - Loop through each keypoint to compute smoothed predictions and variances, adjust predictions based on mean observations, and compute Z-scores using
eks_zscore
.
- Initialize arrays for smoothed means (
-
Final Cleanup:
- Create a pandas DataFrame for each keypoint with smoothed predictions, variances, and Z-scores.
- Append each DataFrame to a list (
dfs
) and a dictionary (df_dicts
).
-
Return Results:
- Return a tuple containing the dictionary of DataFrames and the final smoothing parameters.
This function optimizes the smoothing parameter and uses the result to run the Kalman filter-smoother. It takes in various parameters related to covariance matrices, observations, and initial states, and returns the final smoothing parameters, smoothed means, and smoothed covariances.
cov_mats
(np.ndarray): Covariance matrices.ys
(np.ndarray): Observations with shape (keypoints, frames, coordinates), where coordinate is usually 2.m0s
(np.ndarray): Initial mean state.S0s
(np.ndarray): Initial state covariance.Cs
(np.ndarray): Measurement function.As
(np.ndarray): State-transition matrix.Rs
(np.ndarray): Measurement noise covariance.ensemble_vars
(np.ndarray): Ensemble variances.s_frames
(list): List of frames.smooth_param
(float): Smoothing parameter.blocks
(list): List of blocks for segmenting the data.maxiter
(int): Maximum number of iterations for optimization (default is 1000).
tuple
: A tuple containing:- Final smoothing parameters.
- Smoothed means.
- Smoothed covariances.
- Negative log-likelihoods.
- Negative log-likelihood values.
-
Initialization:
- Extract the number of keypoints (
n_keypoints
) from theys
array. - Initialize an empty list for final smoothing parameters (
s_finals
). - If no blocks are provided, create a block for each keypoint.
- Extract the number of keypoints (
-
Device Check:
- Check if a GPU is available for parallel processing. If available, use the GPU for parallel smoothing parameter optimization. Otherwise, use the CPU for sequential optimization.
-
Define Loss Functions:
- Define
nll_loss_parallel_scan
for GPU usage andnll_loss_sequential_scan
for CPU usage. Both functions ensure positivity by taking the exponential of the smoothing parameter and call the appropriate smoothing function (singlecam_smooth_min_parallel
orsinglecam_smooth_min
).
- Define
-
Smooth Parameter Optimization:
- If a
smooth_param
is provided, use it directly. Otherwise, initialize guesses for each keypoint usingcompute_initial_guesses
and crop the frames usingcrop_frames
. - Optimize the negative log-likelihood for each block of keypoints:
- Initialize the smoothing parameter (
s_init
) with a positive guess. - Set up the optimizer using
optax.adam
. - Select the relevant subsets of the input arrays for the current block.
- Define a
step
function to perform optimization steps. - Iterate the optimization process until convergence or the maximum number of iterations is reached.
- Initialize the smoothing parameter (
- If a
-
Final Smooth:
- After optimization, perform a final forward-backward pass with the optimized smoothing parameters by calling
final_forwards_backwards_pass
.
- After optimization, perform a final forward-backward pass with the optimized smoothing parameters by calling
-
Return Results:
- Return a tuple containing the final smoothing parameters, smoothed means, and smoothed covariances.