✨ feat(data_processing.py): add function to calculate morphological indicators from discrete data The variable name teta_diffs was changed to theta_diffs to improve semantics. A new function was added to calculate morphological indicators from discrete data. The function calculates Tortuosity, Volume, Surface, Mean radius, Standard deviation of radius, Sigma r tot, MI_l, and MI_p. 🔥 refactor(input.py): remove unused result_file_path parameter from ScannedObject constructor and from_xyz_file method ✨ feat(input.py): add encoding parameter to open method in from_obj_file and from_xyz_file methods The result_file_path parameter was not being used in the ScannedObject constructor and from_xyz_file method, so it was removed to simplify the code. The encoding parameter was added to the open method in the from_obj_file and from_xyz_file methods to ensure that the files are opened with the correct encoding. 🐛 fix(output.py): add utf-8 encoding when writing to output file ✨ feat(output.py): remove unused import and function argument, improve code readability The fix adds the utf-8 encoding when writing to the output file to avoid encoding issues. The feat removes the unused import and function argument to improve code readability. The function format_data now only takes the necessary arguments and the unused import is removed. 🐛 fix(main_window.py): fix typo in function name ✨ feat(main_window.py): add persistence to pre-processed data The fix corrects a typo in the function name get_true_theta_from_x_y. The feat adds persistence to the pre-processed data by storing the raw data, discrete data, and advanced data in the main window. This avoids re-computation of the data when switching between tabs. 🎨 style(MainWindow.ui): add export_advanced_metrics button to the UI 🎨 style(UI_MainWindow.py): add export_advanced_metrics button to the UI 🎨 style(ressources_rc.py): update the resource file 🐛 fix(data_extraction.py): fix typo in function name get_mean_teta to get_mean_theta The changes add a new button to the UI named "export_advanced_metrics" which allows the user to export variables. The resource file is updated to reflect the changes. The typo in the function name get_mean_teta is fixed to get_mean_theta.
188 lines
5.1 KiB
Python
188 lines
5.1 KiB
Python
"""
|
|
Created on Mon Apr 17 2023
|
|
@name: data_extraction.py
|
|
@desc: This module contains some utility functions for math operations.
|
|
@auth: Djalim Simaila
|
|
@e-mail: djalim.simaila@inrae.fr
|
|
"""
|
|
import numpy as np
|
|
import math
|
|
|
|
def get_mean(values:list):
|
|
"""
|
|
Get the mean of the values.
|
|
|
|
:param values: values
|
|
:return: mean of the values
|
|
|
|
:Example:
|
|
>>> get_mean([1,2,3,4,5])
|
|
3.0
|
|
"""
|
|
return np.mean(values)
|
|
|
|
def get_standard_deviation(values:list):
|
|
"""
|
|
Get the standard deviation of the values.
|
|
|
|
:param values: values
|
|
:return: standard deviation of the values
|
|
|
|
:Example:
|
|
>>> get_standard_deviation([1,2,3,4,5])
|
|
1.4142135623730951
|
|
"""
|
|
return np.std(values)
|
|
|
|
def get_x_y_z_mean(discrete_values:list):
|
|
"""
|
|
Get the mean of the x and y coordinates in the discrete range.
|
|
|
|
:param x: x coordinates
|
|
:param y: y coordinates
|
|
:return: mean of x and y coordinates in the discrete range
|
|
|
|
:Example:
|
|
>>> get_x_y_z_mean([(1,2,3),(4,5,6),(7,8,9)])
|
|
(4.0, 5.0, 6.0)
|
|
"""
|
|
x = [vertex[0] for vertex in discrete_values]
|
|
y = [vertex[1] for vertex in discrete_values]
|
|
z = [vertex[2] for vertex in discrete_values]
|
|
return get_mean(x), get_mean(y), get_mean(z)
|
|
|
|
def get_radius_from_x_y(xi:float, yi:float, x_mean:float, y_mean:float):
|
|
"""
|
|
Get the radius from the x and y coordinates.
|
|
|
|
:param xi: x coordinate
|
|
:param yi: y coordinate
|
|
:param x_mean: mean of x coordinates in the discrete range
|
|
:param y_mean: mean of y coordinates in the discrete range
|
|
:return: radius for this point
|
|
|
|
:Example:
|
|
>>> get_radius_from_x_y(1,2,3,4)
|
|
2.8284271247461903
|
|
"""
|
|
return np.sqrt(np.power((xi - x_mean), 2) + np.power((yi - y_mean), 2))
|
|
|
|
def get_mean_radius(discrete_values:list):
|
|
"""
|
|
Get the mean of the radius in the discrete range.
|
|
|
|
:param discrete_values: discrete values
|
|
:return: mean of the radius in the discrete range
|
|
|
|
:Example:
|
|
>>> get_mean_radius([(1,2,3),(4,5,6),(7,8,9)])
|
|
2.82842712474619
|
|
"""
|
|
x_mean, y_mean, z_mean = get_x_y_z_mean(discrete_values)
|
|
radius = []
|
|
for x,y,z in discrete_values:
|
|
radius.append(get_radius_from_x_y(x,y,x_mean,y_mean))
|
|
return get_mean(radius)
|
|
|
|
def get_radius_std(discrete_values:list):
|
|
"""
|
|
Get the standard deviation of the radius in the discrete range.
|
|
|
|
:param discrete_values: discrete values
|
|
:return: standard deviation of the radius in the discrete range
|
|
|
|
:Example:
|
|
>>> get_radius_std([(1,2,3),(4,5,6),(7,8,9)])
|
|
2.8284271247461903
|
|
"""
|
|
x_mean, y_mean, z_mean = get_x_y_z_mean(discrete_values)
|
|
radius = []
|
|
for x,y,z in discrete_values:
|
|
radius.append(get_radius_from_x_y(x,y,x_mean,y_mean))
|
|
return get_standard_deviation(radius)
|
|
|
|
def get_mean_theta(discrete_values:list):
|
|
"""
|
|
Get the mean of the theta in the discrete range.
|
|
|
|
:param discrete_values: discrete values
|
|
:return: mean of the theta in the discrete range
|
|
|
|
:Example:
|
|
>>> get_mean_theta([(1,2,3),(4,5,6),(7,8,9)])
|
|
0.7853981633974483
|
|
"""
|
|
x_mean, y_mean, z_mean = get_x_y_z_mean(discrete_values)
|
|
theta = []
|
|
for x,y,z in discrete_values:
|
|
theta.append(get_theta_from_x_y(x,y,x_mean,y_mean))
|
|
return get_mean(theta)
|
|
|
|
def get_theta_from_x_y(xi:float, yi:float, x_mean:float, y_mean:float):
|
|
"""
|
|
Get the theta from the x and y coordinates.
|
|
|
|
:param xi: x coordinate
|
|
:param yi: y coordinate
|
|
:param x_mean: mean of x coordinates in the discrete range
|
|
:param y_mean: mean of y coordinates in the discrete range
|
|
:return: theta for this point
|
|
|
|
:Example:
|
|
>>> get_theta_from_x_y(1,2,3,4)
|
|
0.7853981633974483
|
|
"""
|
|
return math.atan((yi - y_mean)/(xi-x_mean))
|
|
|
|
def get_true_theta_from_x_y(xi:float, yi:float, x_mean:float, y_mean:float):
|
|
"""
|
|
Get the theta from the x and y coordinates.
|
|
|
|
:param xi: x coordinate
|
|
:param yi: y coordinate
|
|
:param x_mean: mean of x coordinates in the discrete range
|
|
:param y_mean: mean of y coordinates in the discrete range
|
|
:return: theta for this point
|
|
|
|
:Example:
|
|
>>> get_true_theta_from_x_y(1,2,3,4)
|
|
0.7853981633974483
|
|
"""
|
|
return math.atan2((xi-x_mean),(yi-y_mean))
|
|
|
|
|
|
def get_difference_from_mean_value(values:list, mean_value:float):
|
|
"""
|
|
Get the difference from the mean value.
|
|
|
|
:param values: values
|
|
:param mean_value: mean value
|
|
:return: difference from the mean value
|
|
|
|
:Example:
|
|
>>> get_difference_from_mean_value([1,2,3,4,5], 3)
|
|
[-2.0, -1.0, 0.0, 1.0, 2.0]
|
|
"""
|
|
return [value - mean_value for value in values]
|
|
|
|
def get_distance_between_two_vertices(vertex_1,vertex_2):
|
|
"""
|
|
Get the distance between two vertices.
|
|
|
|
:param vertex_1: vertex 1
|
|
:param vertex_2: vertex 2
|
|
:return: distance between two vertices
|
|
|
|
:Example:
|
|
>>> get_distance_between_two_vertices((1,2,3),(4,5,6))
|
|
5.196152422706632
|
|
"""
|
|
return np.sqrt(np.power((vertex_1[0] - vertex_2[0]), 2) + np.power((vertex_1[1] - vertex_2[1]), 2) + np.power((vertex_1[2] - vertex_2[2]), 2))
|
|
|
|
|
|
#todo fix examples
|
|
if __name__ == "__main__":
|
|
import doctest
|
|
doctest.testmod()
|
|
|