ShockOscillationAnalysis.inc_tracking package

Submodules

ShockOscillationAnalysis.inc_tracking.inc_tracking module

Created on Wed Feb 28 13:47:27 2024

@author: Ahmed H. Hanfy

class ShockOscillationAnalysis.inc_tracking.inc_tracking.InclinedShockTracking(f: int = 1, D: float = 1, pixelScale: float = 1)

Bases: SOA

InclinedShockDomainSetup(CheckingWidth: int, CheckingHieght: int | list, inclined_ref_line: int | list[int, tuple, tuple], imgShape: tuple, VMidPnt: int = 0, nPnts: int = 0, preview_img: ndarray = None, log_dirc: str = '') tuple[list, int, int]

Setup shock inclination test, provids the test slices info. with aid of the estimated inclined shock line.

Parameters:
  • CheckingWidth (int): Width for shock domain checking (sliceWidth).

  • CheckingHeight (int or list): Height for shock domain checking in px. If a list is provided, it represents a range of heights for generating points [upper limit, lower limit].

  • imgShape (tuple): Shape of the image (y-length, x-length).

  • VMidPnt (int, optional): Vertical midpoint. Default is 0.

  • nPnts (int, optional): Number of points to generate for inclined shock lines. Default is 0.

  • preview_img (np.ndarray, optional): Image for preview as background. Default is None.

  • log_dirc (str): log file directory.

Returns:
tuple: A tuple containing:
  • SlicesInfo (list): List of shock domain slices, [[x-domainStrt,x-domainEnd],y-sliceLoc].

  • nPnts (int): Number of slices generated for inclined shock.

  • inclinationCheck (bool): Boolean indicating whether the shock inclination test is applicable.

Example:
>>> from ShockOscillationAnalysis import InclinedShockTracking as IncTrac
>>> instance = IncTrac(f)
>>> width = 20
>>> height = [10, 20]
>>> shape = (100, 200)
>>> points = 5
>>> slices, nPnts, success = instance.InclinedShockDomainSetup(width, height, shape, nPnts=points)
>>> print(slices, nPnts, success)

Note

  • The function sets up shock inclination testing by visualizing the shock domain.

  • It returns a list of slices location and range, the number of slices, and the inclination applicability.

InclinedShockTracking(img_set: list[ndarray], nSlices: int, Ref: list[int], slice_thickness: int = 1, nReview: int | list[int] = 0, output_dirc: str = '', comment: str = '', **kwargs) tuple

Track and analyze the shock angle in a sequence of images. This function analyzes a series of images to track and calculate the shock angle by fitting a line to the shock locations and computing the corresponding shock angle. The analysis utilizes the RANSAC (Random Sample Consensus) or least squares methods to fit the shock locations and calculate the angle. The function optionally visualizes the tracking results and saves the figures.

Parameters:
  • img_set (list): List of images for shock tracking, the images should be formated as numpy array.

  • nSlices (int): Number of slices to divide the image into for analysis.

  • Ref (list): Reference points for slices [[x_1, x_2, y], …].

  • slice_thickness (int, optional): Thickness of each slice. Default is 1.

  • nReview (int or list, optional): Number or range of images to review. Default is 0.

  • output_dirc (str, optional): Directory to save the review images. Default is ‘’.

  • comment (str): Comment to include in the output filename. Default is an empty string.

  • **kwargs: Additional keyword.

Additional keyword arguments **kwargs may include:
Output background image options:
  • op_bg_path (str): Output background image file path pattern. Supports wildcards.

  • bg_x_crop (tuple[int]): A tuple (y_start, y_end) defining the vertical cropping range. Defaults to the full height of the image.

  • bg_x_crop (tuple[int]): A tuple (x_start, x_end) defining the horizontal cropping range. Defaults to the full width of the image.

  • bg_resize (tuple[int]): A tuple (width, height) defining the new dimensions for resizing. Defaults to the dimensions after cropping.

  • bg_90rotate (bool): Whether to rotate the image 90 degrees clockwise. Defaults to 0 (no rotation).

Review and results options:
  • avg_preview_mode (str): Mode for previewing average angle. ‘avg_all’, ‘avg_ang’ and None (default is None).

  • review_inc_slice_tracking (list or int): Specific slices to track and review.

  • store_n_files (int|list[int]): Specify the first n output results to be stored, or provide a range of output image indices to be stored in the format [start, end].

Confidance:
  • conf_interval (float, optional): Confidence level required for error estimation Ex. 0.95 etc. Default is 0, to not compute the confidance parameters

  • residual_preview (bool): If True, generates a residuals preview plot for visualization. Default is False.

  • osc_boundary (bool): To display the maximum oscilliation domain depending on the analyised image set.

Results display options:
  • op_90rotate: To rotate the output axes by 90 degrees clockwise

  • points_opacity (float): The transperancy of the tracking points from 0 to 1 (default is 1).

  • points_color (str): The color of the tracking points (default is ‘yellow’)

  • uncertain_point_color (str): The color of the uncertain tracked points (default is ‘red’)

  • avg_lin_color (str): The average line color when the avg_preview_mode is not None (default is ‘white’)

  • avg_lin_opacity (float): The transperancy of the average line from 0 to 1 (default is 1)

  • avg_show_txt (bool): To display the angle value or not when the avg_preview_mode is not None (default is True)

  • avg_txt_Yloc (int): y-location of the angle value text in pixels (default is image height minus 100.)

  • avg_txt_size (float): Font size of the Angle value (default is 26pt)

  • M1_color (str): The calculated values of Mach when the avg_preview_mode is not None (default is ‘orange’)

  • M1_txt_size (float): Font size of the Mach number and inflow Angle values (default is 26pt)

  • arc_dia (float): inflow angle arc diameter (default is 80px)

  • arw_len (float): inflow arrow length (default is 50px)

  • b_color (str): boundary domain and lines color for the active osc_boundary (default is ‘tab:orange’)

  • osc_range_opacity (float): The transperancy of the boundary domain from 0 to 1 (default is 0.3)

  • b_lins_opacity (float): The transperancy of the boundary lines from 0 to 1 (default is 1)

Returns:
tuple: A tuple containing two elements:
  • avg_angle_data (np.ndarray): Contains average shock angle, confidence, and standard deviation.

  • avg_midloc_data (np.ndarray): Contains average mid-location of the shock with confidence and standard deviation.

Example:
>>> from ShockOscillationAnalysis import InclinedShockTracking as IncTrac
>>> instance = IncTrac(f)
>>> img_set = [img1, img2, img3]
>>> ref = [[10, 20], [30, 40], [50, 60]]
>>> avg_angle, avg_mid_loc = instance.InclinedShockTracking(img_set, 2, ref, nReview=5)
>>> print(avg_angle, avg_mid_loc)

Note

  • The function performs shock tracking across a series of images and calculates the average shock angle.

  • The function optionally computes the confidence interval and standard deviation for shock location and angle.

  • If nReview is specified as a number, the first nReview images will be reviewed.

  • If nReview is specified as a list, it defines a range of images to review (start, end, step).

  • It uses RANSAC or least squares method to fit the shock locations and calculates the corresponding angle.

Equations:

The shock angle is calculated using the slope \(m\) obtained from the RANSAC or least squares fit:

\[\theta = \arctan(m)\]

where \(m\) is the slope of the shock location vs. the slice’s vertical position.

The confidence interval for the shock angle is calculated as:

\[CI_{\theta} = t_{\alpha/2} \cdot \frac{\sigma_{\theta}}{\sqrt{dof}}\]
where:
  • \(t_{\alpha/2}\) is the t-distribution value for a given confidence level.

  • \(\sigma_{\theta}\) is the standard deviation of the angle.

  • \(dof\) is the degrees of freedom, in case of line analysis \(dof = n_s - 2\) where \(n_s\) number of images. But for statistical analysis \(dof = n_s - 1\)

ShockPointsTracking(path: str, tracking_V_range: list[int | float] = [0, 0], inclination_info: int | list[int, tuple, tuple] = 0, nPnts: int = 0, scale_pixels=True, preview=True, output_directory='', comment='', **kwargs)

This function identifies shock points by slicing a predefined domain of the shock and tracking it at each slice based on the integral method of shock tracking outlined in this article. It operates over a specified vertical range within the images, serving as the core function for inclination shock tracking. Additionally, all keyword arguments for output customization can be passed through this function.

Parameters:
  • path (str): Path to the directory containing the image files.

  • tracking_V_range (list[int | float], optional): Vertical range for tracking shock points, specified as a list with two elements representing the upper and lower bounds (default is [0, 0]).

  • inclination_info (int | list[int, tuple, tuple], optional): Information about the inclination of the shock domain. It can be an integer representing the width of the domain or a list containing the width along with the start and end points of the line defining the inclination (default is 0).

  • nPnts (int, optional): Number of points to be tracked (default is 0).

  • scale_pixels (bool, optional): Whether to scale the pixels in the images (default is True).

  • preview (bool, optional): Whether to preview the images (default is True).

  • output_directory (str, optional): Directory to save the output images (default is ‘’).

  • comment (str, optional): Additional comment for the output (default is ‘’).

  • **kwargs: Additional keyword

Additional keyword arguments **kwargs may include:
Importing image options:
  • n_files (int, optional): To import the first n-files from the given path.

  • every_n_files (int, optional): To import files with a step (default is 1).

  • within_range (list[int], optional): To import files within range [start, end]

  • resize_img (tuple[int], optional): Tuple specifying the dimensions to resize the images to (width, height). Default is the original image shape.

Inflow data options:
  • flow_dir (list, optional): List of tuples containing the measured y-coordinates and the corresponding angles [(y_loc, angle),…].

  • flow_Vxy (list, optional): List of tuples containing the measured y-coordinates and the corresponding velocity components [(y_loc, Vx, Vy),…].

  • angle_interp_kind (str): ‘linear’,’CubicSpline’ or ‘PCHIP’ (default is linear)

Define the domain options and tracking:
  • Ref_x0 (list[int], optional): list of x-coordinates for 2-vertical reference lines [Ref_x01, Ref_x02] used for scaling, used instead of drawing.

  • Ref_y0 (int, optional): y-coordinate of the horizontal reference line [y = 0] used as reference for tracking_V_range, used instead of drawing.

  • slice_thickness (int, optional): Thickness of each slice. Default is 1.

Review and results options:
  • preview (bool): Whether to preview the selected domain for the analysis or not (default is True)

  • review_inc_slice_tracking (int|list[int]): To plot all slices of spacific image or range of images (default is 0)

  • preview_angle_interpolation (bool): If True, plot the angle interpolation for preview. (default is False).

  • avg_preview_mode (str): ‘avg_all’, ‘avg_ang’ and None (default is None).

  • Mach_ang_mode (str): Flag indicating whether to display the Mach number ‘Mach_num’ if inflow data is available or ‘flow_dir’ when the Mach number is available(defaults to None).

  • osc_boundary (bool): To display the oscilliation domain depending on the analyised image set.

  • output_directory (str): The pathe where the output results will be stored (default is ‘’).

  • store_n_files (int|list[int]): Specify the first n output results to be stored, or provide a range of output image indices to be stored in the format [start, end].

Results display options:
  • points_opacity (float): The transperancy of the tracking points from 0 to 1 (default is 1).

  • points_color (str): The color of the tracking points (default is ‘yellow’)

  • uncertain_point_color (str): The color of the uncertain tracked points (default is ‘red’)

  • avg_lin_color (str): The average line color when the avg_preview_mode is not None (default is ‘white’)

  • avg_lin_opacity (float): The transperancy of the average line from 0 to 1 (default is 1)

  • avg_show_txt (bool): To display the angle value or not when the avg_preview_mode is not None (default is True)

  • avg_txt_Yloc (int): y-location of the angle value text in pixels (default is image height minus 100.)

  • avg_txt_size (float): Font size of the Angle value (default is 26pt)

  • M1_color (str): The calculated values of Mach when the avg_preview_mode is not None (default is ‘orange’)

  • M1_txt_size (float): Font size of the Mach number and inflow Angle values (default is 26pt)

  • arc_dia (float): inflow angle arc diameter (default is 80px)

  • arw_len (float): inflow arrow length (default is 50px)

  • b_color (str): boundary domain and lines color for the active osc_boundary (default is ‘tab:orange’)

  • osc_range_opacity (float): The transperancy of the boundary domain from 0 to 1 (default is 0.3)

  • b_lins_opacity (float): The transperancy of the boundary lines from 0 to 1 (default is 1)

Note

  • In case of scale_pixels = True the Ref_x0 and Ref_y0 must be defined either by drawing or as arguments.

  • The values of Ref_x0 and Ref_y0 are in pixels.

  • tracking_V_range values are in pixels, but if scale_pixels = True, the values should match the scale units [for example mm].

  • The imported files are defined by thier index and sorted by name.

  • For automation it is better to set preview to False.

  • The plots from review_inc_slice_tracking give details of finding the shock location, such as local minima, shock location, last image shock location, etc.

  • avg_preview_mode the display of vertical least squares regression line of the tracked points:
    • ‘avg_all’: Displays the average of all lines calculated from the tracked points across the entire image dataset.

    • ‘avg_ang’: Displays the line of the tracked points in each image

  • In this version Mach_ang_mode can only calculate Mach number when inflow data is available, ‘flow_dir’ is not yet supported!

  • osc_boundary Calculated based on the minimum and maximum recorded location at each slice, a vertical least squares regression line is used to define the oscillation boundary and minimize any uncertainty that might occur.

Returns:

tuple[float, float]: Average inclination angle and average shock location.

Example:
>>> from ShockOscillationAnalysis import InclinedShockTracking as IncTrac
>>> D = 60
>>> imgPath = r'C:\Usersdmin\Pictures\*.png'
>>> IncTrac = IncTrac(D = D)
>>> IncTrac.ShockPointsTracking(imgPath, scale_pixels = True,
                                tracking_V_range = [5, 25],
                                nPnts = 9, inclination_info = [100, (249, 0), (0, 429)], slice_thickness = 4,
                                points_opacity = 0.0,
                                avg_preview_mode = 'avg_all', avg_show_txt = True, avg_txt_Yloc = 400, avg_txt_size = 30,
                                preview = True,
                                osc_boundary = True)
Steps:
  1. Define reference vertical boundaries (for scaling). Draw or assine them in this parameter Ref_x0,

  2. Define reference horizontal line as the y-datum. Draw or assine it in this parameter Ref_y0,

  3. Define the estimated line of shock. Draw or assine it as two points in this parameter inclination_info as in the example

  4. Run shock tracking function within the selected vertical range tracking_V_range.

  5. The function will perform the tracking after dividing the vertical range into nPnts.

ShockOscillationAnalysis.inc_tracking.inc_tracking_support module

Created on Wed Jun 5 10:15:04 2024

@author: Ahmed H. Hanfy

ShockOscillationAnalysis.inc_tracking.inc_tracking_support.ImportingFiles(pathlist: list[str], indices_list: list[int], n_images: int, imgs_shp: tuple[int], import_type='gray_scale', log_dirc: str = '', **kwargs) dict[int, ndarray]

Import images from specified paths, optionally crop, resize or rotate them.

Parameters:
  • pathlist (list[str]): List of paths to the image files to be imported.

  • indices_list (list[int]): List of indices indicating which images from pathlist should be imported.

  • n_images (int): Number of images to import.

  • imgs_shp (tuple[int]): Desired shape of the images (height, width).

  • import_type (str, optional): Type of image import. Can be ‘gray_scale’ for grayscale images or ‘other’ for other types. Default is ‘other’.

  • log_dirc (str): log file directory.

  • kwargs (dict, optional): Additional parameters:
    • resize_img (tuple[int], optional): Tuple specifying the desired dimensions for resizing the images (width, height). Default is the original shape of the images.

    • crop_y_img (tuple[int], optional): Tuple specifying the cropping range along the y-axis (min, max). Default is to crop the entire image along y.

    • crop_x_img (tuple[int], optional): Tuple specifying the cropping range along the x-axis (min, max). Default is to crop the entire image along x.

    • rotate90_img (int, optional): If set to 1, rotates the images 90 degrees clockwise. Default is 0 (no rotation).

Returns:
  • tuple:
    • img_list (dict[int, np.ndarray]): Dictionary where the keys are indices from indices_list and the values are the corresponding processed images.

Example Flow:
  1. Import images from the list of paths specified in pathlist based on the indices in indices_list.

  2. Apply cropping if specified in kwargs.

  3. Resize the images based on resize_img parameter if provided.

  4. Rotate the images 90 degrees if rotate90_img is set to 1.

  5. Return a dictionary of images, indexed by the values in indices_list.

Example:
>>> from ShockOscillationAnalysis import InclinedShockTracking as IncTrac
>>> instance = IncTrac(f)
>>> pathlist = ['path/to/image1.jpg', 'path/to/image2.jpg']
>>> indices = [0, 1]
>>> n_images = 2
>>> shape = (100, 200)
>>> original_imgs, processed_imgs = instance.ImportingFiles(pathlist, indices, n_images, shape)
>>> print(original_imgs, processed_imgs)

Note

  • The function uses different import functions based on the import_type parameter.
    • If the type is ‘gray_scale’, the import_gray function is used to convert the images to grayscale.

    • Otherwise, the other function is used for other image types.

  • Images are resized to the specified dimensions if resize_img is provided in the keyword arguments.

  • Cropping is applied to the images based on crop_x_img and crop_y_img parameters, and the images can optionally be rotated by 90 degrees.

  • Progress is displayed on the console while the images are being imported.

ShockOscillationAnalysis.inc_tracking.inc_tracking_support.anglesInterpolation(pnts_y_list: list[int], flow_dir: list[float] = None, flow_Vxy: list[tuple] = None, log_dirc: str = '', **kwargs) list[float]

Interpolate angles based on given y-coordinates and corresponding angles or velocity components.

Parameters:
  • pnts_y_list (list): List of y-coordinates to interpolate angles for.

  • flow_dir (list, optional): List of tuples containing the measured y-coordinates and the corresponding angles [(y_loc, angle),…].

  • flow_Vxy (list, optional): List of tuples containing the measured y-coordinates and the corresponding velocity components [(y_loc, Vx, Vy),…].

  • **kwargs: Additional keyword arguments:
    • angle_interp_kind (str):

    • preview_angle_interpolation (bool): If True, plot the angle interpolation for preview. Default is False.

Returns:

list: Interpolated angles for each y-coordinate in pnts_y_list. If the y-domain is out of valid range, returns an empty list.

Example:
>>> from ShockOscillationAnalysis import InclinedShockTracking
>>> instance = InclinedShockTracking()
>>> pnts_y = [5, 15, 25]
>>> flow_dir = [(0, 10), (10, 20), (20, 30)]
>>> interpolated_angles = instance.anglesInterpolation(pnts_y, flow_dir)
>>> print(interpolated_angles)

Note

  • interpolation can be performed using multible methods ‘linear’,’CubicSpline’ and ‘PCHIP’ for better inflow representation
    • If ‘linear’, linear interpolation will be performed. Default is ‘linear’.

    • If ‘CubicSpline’, Interpolate data with a piecewise cubic polynomial which is twice continuously differentiable.

    • If ‘PCHIP’, PCHIP 1-D monotonic cubic interpolation will be performed.

  • If a y-coordinate in pnts_y_list is out of the range defined by flow_dir or flow_Vxy, the function will consider only boundary angles.

  • If both flow_dir and flow_Vxy are provided, flow_dir will take precedence.

See also

ShockOscillationAnalysis.inc_tracking.inc_tracking_support.doNone(img)
ShockOscillationAnalysis.inc_tracking.inc_tracking_support.import_gray(img, resize_img)
ShockOscillationAnalysis.inc_tracking.inc_tracking_support.import_other(img, resize_img)
ShockOscillationAnalysis.inc_tracking.inc_tracking_support.pearson_corr_coef(xLoc: list[float], columnY: list[float], nSlices: int) list[float]

Calculate the Pearson correlation coefficient.

Parameters:
  • xLoc (list[float]): List of x-coordinates of the points.

  • columnY (list[float]): List of y-coordinates of the points.

  • nSlices (int): Number of slices or data points.

Returns:

float: Pearson correlation coefficient.

Example:
>>> from ShockOscillationAnalysis import InclinedShockTracking
>>> instance = InclinedShockTracking()
>>> nSlices = 5
>>> xLoc = [1, 2, 3, 4, 5]
>>> columnY = [2, 4, 6, 8, 10]
>>> nSlices = 5
>>> r = instance.pearson_corr_coef(xLoc, columnY, nSlices)
>>> print(r)

Note

  • The function calculates the Pearson correlation coefficient using the formula:

    \[r = \frac{n \sum (xy) - (\sum x)(\sum y)}{\sqrt{[n \sum x^2 - (\sum x)^2][n \sum y^2 - (\sum y)^2]}}\]
  • It returns the Pearson correlation coefficient as a float.

ShockOscillationAnalysis.inc_tracking.inc_tracking_support.ransac(x: ndarray, y: ndarray, threshold: float, e: float = 0.3, p: float = 0.999, n_samples: int = 5, max_trials: int = 0, log_dirc: str = '') tuple[float]

Perform RANSAC (Random Sample Consensus) algorithm for robust linear model fitting.

This function identifies the best linear model for a dataset with potential outliers by iteratively fitting models to random subsets of the data and evaluating their inlier scores.

Parameters:
  • x (np.ndarray): Array of independent variable values.

  • y (np.ndarray): Array of dependent variable values.

  • threshold (float): Threshold for classifying points as inliers based on their residuals.

  • e (float, optional): Estimated outlier ratio. Defaults to 0.3. Represents the proportion of outliers in the dataset.

  • p (float, optional): Desired probability of selecting at least one outlier-free subset. Defaults to 0.999.

  • n_samples (int, optional): Number of random points to select for model fitting in each iteration. Defaults to 5.

  • max_trials (int, optional): Maximum number of RANSAC iterations. Defaults to 0, where the number of trials is automatically computed based on e and p.

  • log_dirc (str): log file directory.

Returns:
  • tuple:
    • best_model (float): The slope of the best-fitting linear model.

    • best_inlier_xmean (float): Mean of the x-coordinates of the inliers corresponding to the best model.

    • best_inlier_ymean (float): Mean of the y-coordinates of the inliers corresponding to the best model.

Raises:
  • Exception: If the algorithm fails to find a valid model, the function will print debugging information.

Equations:
  • The number of iterations \(n_{tries}\); however, can be roughly determined as a function of the desired probability of success \(p\) as shown below.

    \[n_{tries} = \frac{\log(1 - p)}{\log(1 - (1 - e)^{n_s})}\]

    where: \(e\) is number of inliers in data to number of points in data. here assumed to be 30% of the points are inlier and \(n_s\) is the sample size among the existed points

  • The outliers are estimated based on the distance between the existing points and predected line as follow:

    \[e = |x - x_{pred}|\]

    where:

    \[ \begin{align}\begin{aligned}x_{pred} = \begin{cases} \frac{y - c}{m} \ \forall m != \infty \\\ \overline{x} \ \forall m = \infty \end{cases}\end{aligned}\end{align} \]
Example:
>>> import numpy as np
>>> x = np.array([1, 2, 3, 4, 5])
>>> y = np.array([2.1, 4.2, 6.1, 8.0, 10.2])
>>> threshold = 0.5
>>> slope, inlier_mean = ransac(x, y, threshold)
>>> print("Slope:", slope)
>>> print("Inlier mean:", inlier_mean)

Note

  • The number of tracking points should be more than the sample size \(n_s\) by 1 at least

  • This function relies on the v_least_squares function for linear model fitting.

  • Outliers are automatically excluded based on the residual threshold.

  • The function is designed to handle datasets with a moderate proportion of outliers.

ShockOscillationAnalysis.inc_tracking.inc_tracking_support.rotate90(img)

Rotate an image 90 degrees clockwise.

This function transposes the image matrix (swaps rows and columns) and flips it horizontally to achieve a 90-degree clockwise rotation.

Parameters:
  • img (numpy.ndarray): Input image as a NumPy array. The image should be in a standard format (e.g., grayscale or RGB) compatible with OpenCV operations.

Returns:
  • numpy.ndarray: Rotated image with the same format as the input.

Example:
>>> import cv2
>>> img = cv2.imread('example.jpg')  # Load an image
>>> rotated_img = rotate90(img)     # Rotate it 90 degrees
>>> cv2.imshow('Rotated Image', rotated_img)  # Display the rotated image
>>> cv2.waitKey(0)
>>> cv2.destroyAllWindows()
ShockOscillationAnalysis.inc_tracking.inc_tracking_support.shockDomain(Loc: str, P1: tuple[int], HalfSliceWidth: int, LineSlope: float, imgShape: tuple[int], preview_img: ndarray = None) float

Generate and visualize a shock domain based on the slice width and the drawn line parameters (one point and slope).

Parameters:
  • Loc (str): The shock direction, either ‘up’ or ‘down’.

  • P1 (tuple): The starting point of the shock domain.

  • HalfSliceWidth (int): Half the width of the slice.

  • LineSlope (float): Slope of the inclined line.

  • imgShape (tuple): Image size (y-length, x-length).

  • preview_img (optional): Image for previewing the shock domain. Default is None.

Returns:

float: The y-intercept of the inclined line.

Example:
>>> from ShockOscillationAnalysis import InclinedShockTracking
>>> instance = InclinedShockTracking()
>>> slope_intercept = instance.shockDomain('up', (10, 20), 5, 0.5, (100, 200))
>>> print(slope_intercept)

Note

  • The function generates and visualizes a shock domain line based on the specified parameters.

  • It returns the y-intercept of the inclined line.

ShockOscillationAnalysis.inc_tracking.inc_tracking_support.v_least_squares(xLoc: list[float], columnY: list[float], nSlices: int) list[float]

Perform a vertical least squares linear regression to find the slope.

Parameters:
  • xLoc (list[float]): List of x-coordinates of the points.

  • columnY (list[float]): List of y-coordinates of the points.

  • nSlices (int): Number of slices or data points.

Returns:

float: The slope of the best-fit line. Returns inf if the slope cannot be determined (e.g., division by zero).

Example:
>>> xLoc = [1, 2, 3, 4, 5]
>>> columnY = [2, 4, 6, 8, 10]
>>> nSlices = 5
>>> slope = v_least_squares(xLoc, columnY, nSlices)
>>> print(slope)  # Output: 2.0

Note

  • The function calculates the slope of the best-fit line using the vertical least squares method.

  • If the denominator in the formula is zero, the function returns np.inf.

Equations:
  • The slope \(m\) is calculated using the formula:

    \[m = \frac{n \cdot \sum (y^2) - (\sum y)^2}{n \cdot \sum (x \cdot y) - (\sum x)(\sum y)}\]

    where \(n\) is the number of points (slices).

ShockOscillationAnalysis.inc_tracking.tracking_accuracy module

Created on Tue Nov 5 10:15:04 2024

@author: Ahmed H. Hanfy

ShockOscillationAnalysis.inc_tracking.tracking_accuracy.IQR(error: list[float], y_dp: list[float], columnY: list[int], uncertain_y: list[int], count: int = 0, img_indx: list[int] = None, output_directory: str = '', comment: str = '', **kwargs) list[tuple[float, int, int]]

Detect outliers in a dataset using the Interquartile Range (IQR) method, calculate leverage, and log significant results if leverage exceeds a specified threshold.

Parameters:
  • error (list[float]): Array of error values to analyze.

  • y_dp (list[float]): Data points used to calculate leverage values for each error.

  • columnY (list[int]): Indexes corresponding to the vertical axis or other tracking information.

  • uncertain_y (list[int]): Y-values or column indexes considered uncertain.

  • count (int, optional): Index counter for the current dataset or image. Default is 0.

  • img_indx (list[int], optional): List of image indices for reference in logs. Default is None.

  • output_directory (str, optional): Directory to save outlier logs. Default is an empty string.

  • comment (str, optional): Comment to append to log filenames. Default is an empty string.

Keyword Arguments:
  • residual_preview (bool, optional): If True, generates a residuals preview plot for visualization. Default is False.

Returns:
  • list[tuple[float, int, int]]: List of detected outliers as tuples:
    • float: The error value.

    • int: Position (index) of the error in the dataset.

    • int: The count index of the current dataset.

Example:
>>> errors = [1.2, 0.5, 3.6, 2.1, 1.8]
>>> y_dp = [0.1, 0.05, 0.2, 0.15, 0.12]
>>> colY = [1, 2, 3, 4, 5]
>>> uncertain_y = [2, 3, 4]
>>> outliers = IQR(errors, y_dp, colY, uncertain_y, count=1, output_directory='logs', comment='test')
>>> print(outliers)

Note

  • Leverage threshold \(H_0 = \frac{3(p+1)}{n_s}\) where \(p\) is the number of independant variable (which is 1 in this condition). That ensures that significant points influencing the model are flagged.

  • Uses the IQR method to identify outliers robustly, focusing on uncertain data columns.

  • Relies on save_data_txt to log outlier details to a text file.

  • Visualization of residuals requires enabling residual_preview.

_images/IQR.png
Equations:
  • Median: \(e_{median} = \text{median}(e^2)\) where \(e = x - x_{pred}\) and \(x\) the detected shock location and \(x_{pred}\) is the loction on the fitted line with RANSAC or least square

  • Quartiles: \(Q1, Q2 = \text{median of lower and upper halves of sorted}(e^2)\)

  • Interquartile Range: \(\text{IQR} = Q2 - Q1\)

  • Outlier Detection: \(outlier < Q1-1.5IQR < IQR < Q2+1.5IQR < outlier\)

  • Leverage of each point: \(H_i = \frac{1}{n_{Slices}} + y_{dp[i]}\) where \(y_{dp[i]} = \frac{(y_i - \overline{y})^2}{\sum{(y_i - \overline{y})^2}}\) and \(y\) is independant variable represents the vertical location of the slice and \(i\) is the point index

ShockOscillationAnalysis.inc_tracking.tracking_accuracy.compute_weighted_average(slope: ndarray, Sm: ndarray, img_set_size: int) tuple[float]

Computes the weighted average slope, uncertainty, and weighted average angle.

Parameters:
  • slope (np.ndarray): Array of slope values.

  • Sm (np.ndarray): Array of standard diviation error associated with the slopes.

  • img_set_size (int): Total number of images in the dataset.

Returns:
tuple[float, float]: A tuple containing:
  • Sm_avg (float): Combined uncertainty of the average slope.

  • w_avg_ang (float): Weighted average angle in degrees, considering zero-uncertainty cases.

Note

  • Handles cases where uncertainties are zero by considering their corresponding angles directly in the weighted average.

Equations:
  • Weighted Average Slope has two conditions:

    \[ \begin{align}\begin{aligned}\overline{m_1}=\frac{\sum_{i}^{N-r}\frac{m_i}{Sm_i^2}}{\sum_{i}^{N-r}\frac{1}{\sigma_i^2}}\forall\ \sigma_i>0,\\\overline{m_2}=\sum_{i}^{r}m_i\forall\ \sigma_i=0\end{aligned}\end{align} \]

    where \(\sigma_i=\frac{s}{\sqrt{\sum\left(Y_j-\overline{Y}\right)^2}}\), \(s\) is the standard error. \(Y_j\) is the slice location, \(\overline{Y}\) is the mean $y$-location of the slices, \(N\) is the total number of images, and \(r\) is the number of images when \(\sigma_i = 0\).

  • Compine Weighted Average slope (including zero-uncertainty cases):

    \[\overline{m_{wj}}=\frac{\left(\left(N-r\right)\overline{m_1}+r\overline{m_2}\right)}{N}\]
  • Uses the relationship between slope and angle:

    \[\theta_i = \arctan(m_{wj}) \cdot \frac{180}{\pi}\]
ShockOscillationAnalysis.inc_tracking.tracking_accuracy.conf_lim(xlocs: list[list[float]], midLocs: list[float], columnY: list[int], y_avg: list[float], slope: list[float], img_indx: list[int], shock_deg: list[float], e: list[list[float]], pop_ylist: list[int], uncertainY_list: list[list[int]], output_directory: str = '', comment: str = '', **kwargs) tuple[list[list[float]], list[int], list[float], list[float], list[float], float, float]

This function calculates the confidence limits for shock angles based on the provided shock tracking data. It identifies outliers using statistical methods and updates the slopes and mid-locations of the shock points. The function also computes the weighted average of the shock angles and the associated confidence interval for the slope.

Parameters:
  • xlocs (list[list[float]]): The x-coordinates for each slice of the shock wave.

  • midLocs (list[float]): The midpoint locations for each image.

  • columnY (list[int]): Y-values corresponding to each slice.

  • y_avg (list[float]): The average Y values used for reference.

  • slope (list[float]): The slope values for each image.

  • shock_deg (list[float]): The estimated shock angle in degrees for each image.

  • img_indx (list[int]): Indexes of the images.

  • e (list[list[float]]): Error values for each slice.

  • pop_ylist (list[int]): List of Y values for removed points from slices.

  • uncertainY_list (list[list[int]]): Indices where the Y-values are uncertain.

  • output_directory (str, optional): Directory to save the output images (default is ‘’).

  • comment (str, optional): Additional comment for the output (default is ‘’).

  • **kwargs: additional keyword arguments

    Additional parameters for the functions error_analysis, IQR, and others.

Returns:
tuple
  • e: List of error values for each slice.

  • pop_ylist: Updated list of Y-values.

  • slope: updated list of slops

  • shock_deg: updated list of shock angles in degrees

  • midLocs: updated list of average x-locations

  • w_avg_ang: Weighted average shock angle.

  • conf_ang: Confidence angle for the weighted average.

Example:
>>> xlocs = [[1.0, 2.0], [2.0, 3.0]]
>>> midLocs = [5.0, 5.5]
>>> columnY = [100, 200]
>>> y_avg = 150
>>> slope = [0.1, 0.15]
>>> img_indx = [1, 2]
>>> e = [[] for _ in range(len(xlocs))]
>>> pop_ylist = [50, 60]
>>> conf_lim = 0.95
>>> uncertainY_list = [[0, 1], [1, 2]]
>>> result = conf_lim(xlocs, midLocs, columnY, y_avg, slope, img_indx, e, pop_ylist, uncertainY_list, conf_interval=conf_lim)
>>> print(result)

Note

  • The conf_lim is typically set to values such as 0.95 for 95% confidence.

  • The function assumes that the number of slices is greater than 3; otherwise, it returns an error message.

  • The outlier_correction step updates the outlier values based on statistical analysis.

ShockOscillationAnalysis.inc_tracking.tracking_accuracy.error_analysis(xloc: list[float], columnY: list[float], nSlices: int, l_slope: float, l_yint: float, t: float, y_dp: list[float])

Estimate confidence intervals for x-locations based on a linear model and calculate residuals.

Parameters:
  • xloc (list[float]): List of actual x-coordinates.

  • columnY (list[float]): List of y-coordinates.

  • nSlices (int): Number of data points.

  • l_slope (float): Slope of the linear regression line.

  • l_yint (float): y-intercept of the linear regression line.

Returns:
tuple:
  • list of tuples: Each tuple contains:
    • Predicted x-location (float)

    • Confidence interval (float)

    • Prediction interval (float)

  • float: Standard error of the residuals.

Raises:

ValueError If nSlices is less than 3 (as at least 2 degrees of freedom are required).

Example:
>>> xloc = [1.2, 2.3, 3.4, 4.5]
 >>> columnY = [2.1, 3.2, 4.3, 5.4]
 >>> nSlices = 4
 >>> l_slope = 1.0
 >>> l_yint = 1.0
 >>> t = 2.776  # t-statistic for 95% confidence with 2 degrees of freedom
 >>> y_dp = [0.1, 0.2, 0.3, 0.4]
 >>> intervals, std_error = error_analysis(xloc, columnY, nSlices, l_slope, l_yint, t, y_dp)
 >>> print(intervals)
 [(1.1, 0.28, 0.38), (2.1, 0.36, 0.47), (3.2, 0.45, 0.56), (4.3, 0.56, 0.68)]
 >>> print(std_error)
 0.134

Note

This function calculates the residual sum of squares and confidence intervals for the given x-locations based on a linear fit to the corresponding y-values. The confidence interval is computed using the t-distribution for the specified number of slices.

_images/CIandPI.png
Equations:
  • Residuals are calculated as:

    \[e_i = x_i - x_{pred [i]}\]

    where \(x_{pred [i]}\) is the predicted x-location based on the fitted line.

  • Confidence Interval:

    \[CI_i = t_{\alpha/2} \cdot s \cdot \sqrt{\frac{1}{n_s} + y_{\text{dp[i]}}}\]
    where:
    • \(t_{\alpha/2}\) is the t-distribution value for a given confidence level.

    • \(s = \sqrt{SSE/dof}\) is the standard error where \(SSE = \sum{e_i^2}\) is the sum of the squre error and \(dof\) is the degree of freedom, in case of line analysis \(dof = n_s - 2\) and \(n_s\) is number of slices.

    • \(y_{dp[i]} = \frac{(y_i - \overline{y})^2}{\sum{(y_i - \overline{y})^2}}\) and \(y\) is independant variable represents the vertical location of the slice

  • Prediction Interval:

    \[PI_i = t_{\alpha/2} \cdot \sqrt{s^2 + \text{CI}^2}\]
ShockOscillationAnalysis.inc_tracking.tracking_accuracy.outlier_correction(outliers_set: list[list[float, int, int]], xlocs: list[list[float]], columnY: list[int], t: float, log_dirc: str = '') list[list[float, float, list[int], float, float]]

Corrects for outliers by iteratively removing them, recalculating slopes, midpoints, and associated statistics.

Parameters:
  • outliers_set (list): List of outliers, each described by [value, index, set_index].

  • xlocs (list): List of x-locations for each dataset.

  • columnY (list): List of y-values.

  • t (float): t-value for statistical analysis.

Returns:
  • correction: List of corrected parameters:

    [new_slope, new_midpoint, removed_outliers, new_Sm, new_Sty].

ShockOscillationAnalysis.inc_tracking.tracking_accuracy.pop_outlier(indx: int, xloc: ndarray, columnY: ndarray, n_slice_new: int, log_dirc: str = '') tuple

Removes an outlier at a given index and recomputes the RANSAC-based shock slope.

Parameters:
  • indx (int): Index of the outlier to remove.

  • xloc (np.ndarray): Array of x-locations.

  • columnY (np.ndarray): Corresponding y-values.

  • n_slice_new (int): Number of slices after removing the outlier (not used in function body).

  • log_dirc (str, optional): log file directory. Default is ‘’.

Returns:
tuple:
  • new_shock_slope (float): Slope estimated after removing the outlier.

  • new_midxloc (np.ndarray): Fitted x-locations from RANSAC.

  • new_midyloc (np.ndarray): Fitted y-locations from RANSAC.

  • newxloc (np.ndarray): xloc after removing the outlier.

  • newyloc (np.ndarray): columnY after removing the outlier.

  • removed_point (list): The removed [x, y] outlier point.

  • new_count (int): Length of the updated y-array.

ShockOscillationAnalysis.inc_tracking.tracking_accuracy.save_data_txt(outlier_p: list[tuple[float, int]], hi: ndarray, leverage_lim: float, img_indx: int = None, output_directory: str = '', comment: str = '')

Save outlier data and leverage information to a text file.

This function logs detected outliers and leverage information into a text file for analysis and review.

Parameters:
  • outlier_p (list[tuple[float, int, any]]): List of detected outliers.
    Each entry is a tuple containing:
    • Error (float): Magnitude of the error for the outlier.

    • Position (int): Position of the detected outlier.

    • Index (int): Image index.

  • hi (np.ndarray): Array of leverage values for the dataset.

  • leverage_lim (float): Leverage limit for identifying influential points.

  • img_indx (int, optional): Index or identifier for the image being analyzed. Default is None, which records “N/A” in the log.

  • output_directory (str, optional): Directory to save the output file. Default is an empty string, which saves to the current working directory.

  • comment (str, optional): Additional comment to append to the output file name. Default is an empty string.

Returns:
  • None

Example:
>>> outliers = [(0.12, 3, None), (0.15, 7, None)]
>>> leverage_values = np.array([0.1, 0.2, 0.15, 0.08])
>>> leverage_limit = 0.2
>>> save_data_txt(outliers, leverage_values, leverage_limit, img_indx=5, output_directory='logs', comment='test')

Note

  • The output file is named outliers_<comment>.txt, where <comment> is an optional user-provided string.

  • Appends data to the file if it already exists; otherwise, creates a new file.

  • Uses leverage values to summarize data points that might have significant influence.