From 67c4b4414326949f85d5fd613e4dce5cf725cd13 Mon Sep 17 00:00:00 2001 From: vinush-vignes Date: Fri, 9 Feb 2024 12:48:51 +0000 Subject: [PATCH] added interpolation method kws --- openep/analysis/_conduction_velocity.py | 44 +++++++++++++++++++++++-- openep/analysis/analyse.py | 26 +++++++++++---- openep/case/case_routines.py | 1 + openep/converters/pyvista_converters.py | 2 +- 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/openep/analysis/_conduction_velocity.py b/openep/analysis/_conduction_velocity.py index 117ff16d..e251b0b5 100644 --- a/openep/analysis/_conduction_velocity.py +++ b/openep/analysis/_conduction_velocity.py @@ -160,10 +160,10 @@ def triangulation( Perform triangulation on electrogram data to calculate conduction velocities. Args: - bipolar_egm_pts (array-like): + bipolar_egm_pts (array): Array of bipolar electrogram points of size Nx3 - local_activation_time (array-like): + local_activation_time (array): Local activation times corresponding to bipolar_egm_pts. min_theta (float): @@ -291,16 +291,54 @@ def divergence( local_activation_time, collision_threshold=-1, focal_threshold=1, - output_binary_field=False + output_binary_field=False, + interpolation_kws=None, ): + """ + Calculate divergence of the conduction velocity (CV) field to identify regions of collision and + focal activation within cardiac tissue based on local activation times (LATs) and electrogram points. + + Args: + case (Case): The case object containing cardiac geometry and electrogram data. + + bipolar_egm_pts (np.ndarray): An array of coordinates for bipolar electrogram points. + + local_activation_time (np.ndarray): An array of local activation times corresponding to + bipolar electrogram points. + + collision_threshold (float, optional): Divergence value below which regions are considered + as collision fronts. Defaults to -1. + + focal_threshold (float, optional): Divergence value above which regions are considered as + focal activation fronts. Defaults to 1. + + output_binary_field (bool, optional): If True, the output divergence field is binary, with 1 + indicating regions meeting the collision or focal threshold, + and 0 otherwise. If False, the continuous divergence field + is returned. Defaults to False. + + interpolation_kws (dict, optional): Keyword arguments for interpolation function. + > interpolate_general_cloud_points_onto_surface(**interpolation_kws) + Defaults to None. + + Returns: + tuple: A tuple containing two elements: + - norm_cv_direction (np.ndarray): The normalized direction of conduction velocity + across the cardiac tissue surface. + - divergence (np.ndarray): The divergence of the activation direction field. This + can either be a continuous field or a binary field indicating focal and collision + regions based on the 'output_binary_field' parameter. + """ temp_mesh = case.create_mesh() basic_mesh = pv.PolyData(temp_mesh.points, temp_mesh.faces) + interpolation_kws = dict() if interpolation_kws is None else interpolation_kws interpolated_scalar = interpolate_general_cloud_points_onto_surface( case=case, cloud_values=local_activation_time, cloud_points=bipolar_egm_pts, + **interpolation_kws ) basic_mesh['LAT_scalar'] = interpolated_scalar diff --git a/openep/analysis/analyse.py b/openep/analysis/analyse.py index 4fb50af2..ced65679 100644 --- a/openep/analysis/analyse.py +++ b/openep/analysis/analyse.py @@ -81,8 +81,9 @@ def calculate_cv( method='triangulation', include=None, apply_scalar_field=True, - **kwargs - ): + interpolation_kws=None, + **method_kwargs + ): """ Calculate the conduction velocity and interpolate points onto a mesh. @@ -104,7 +105,12 @@ def calculate_cv( apply_scalar_field (bool, optional): If True, applies the calculated conduction velocity values as a scalar field on the case object's mesh. Defaults to True. - **kwargs: Additional keyword arguments specific to the chosen calculation method. + + interpolation_kws (dict, optional): Keyword arguments for interpolation function. + > interpolate_general_cloud_points_onto_surface(**interpolation_kws) + Defaults to None. + + **method_kwargs: Additional keyword arguments specific to the chosen calculation method. Returns: tuple: A tuple containing two elements: @@ -128,17 +134,19 @@ def calculate_cv( if method.lower() not in supported_cv_methods: raise ValueError(f"`method` must be one of {supported_cv_methods.keys()}.") + interpolation_kws = dict() if interpolation_kws is None else interpolation_kws include = self._case.electric.include.astype(bool) if include is None else include lat, bipolar_egm_pts = preprocess_lat_egm(self._case, include) cv_method = supported_cv_methods[method] - self._values, self._centers = cv_method(bipolar_egm_pts, lat, **kwargs) + self._values, self._centers = cv_method(bipolar_egm_pts, lat, **method_kwargs) if apply_scalar_field: self._case.fields.conduction_velocity = interpolate_general_cloud_points_onto_surface( case=self._case, cloud_values=self.values, cloud_points=self.centers, + **interpolation_kws ) return self.values, self.centers @@ -180,7 +188,8 @@ def calculate_divergence( self, include=None, output_binary_field=False, - apply_scalar_field=True + apply_scalar_field=True, + interpolation_kws=None, ): """ Calculate the divergence of conduction velocity and optionally apply the result as a scalar field. @@ -199,6 +208,10 @@ def calculate_divergence( the case object. Defaults to True. + interpolation_kws (dict, optional): Keyword arguments for interpolation function. + > interpolate_general_cloud_points_onto_surface(**interpolation_kws) + Defaults to None. + Returns: tuple of (np.ndarray, np.ndarray): A tuple containing the divergence direction and divergence values. The direction is a 2D array of shape (N, 3), where N is the number @@ -218,7 +231,8 @@ def calculate_divergence( case=self._case, bipolar_egm_pts=bipolar_egm_pts, local_activation_time=lat, - output_binary_field=output_binary_field + output_binary_field=output_binary_field, + interpolation_kws=interpolation_kws, ) if apply_scalar_field: diff --git a/openep/case/case_routines.py b/openep/case/case_routines.py index 12fe6e68..69249c0d 100644 --- a/openep/case/case_routines.py +++ b/openep/case/case_routines.py @@ -76,6 +76,7 @@ class and associated keyword arguments to the `method` and `method_kws` 'interpolate_activation_time_onto_surface', 'interpolate_voltage_onto_surface', 'bipolar_from_unipolar_surface_points', + 'interpolate_general_cloud_points_onto_surface' ] diff --git a/openep/converters/pyvista_converters.py b/openep/converters/pyvista_converters.py index e670b8aa..92a6c893 100644 --- a/openep/converters/pyvista_converters.py +++ b/openep/converters/pyvista_converters.py @@ -93,7 +93,7 @@ def to_pyvista( mesh.point_data["LAT"] = case.fields.local_activation_time mesh.point_data["Impedance"] = case.fields.impedance mesh.point_data["Force"] = case.fields.force - mesh.point_data["Conduction Velocity"] = case.fields.conduction_velocity + mesh.point_data["Conduction velocity"] = case.fields.conduction_velocity mesh.point_data["Divergence"] = case.fields.cv_divergence return mesh