The overall functions should be used in the sequence below

Each of the functions calls sub functions in the flow presented in the graph below

An example of the original image is shown below,

FilterBackground(image): as the image is messy, this function take the connected convexHull to clean up everything outside this hull.
image (numpy 2d uint8 array): the original image

GetEventPositions(pic,debug_mode=0, center_width = 12, quadrant_thresh=100, center_thresh=300, err_thresh =12, spread_thresh=6 ): get all the three tip points and also the vertex point
pic (numpy 2d uint8 array): the original image
debug_mode (bool): plot some debug features, this should be turned off in batch mode
center_width (float): not used for now
quadrant_thresh (float): threshold for number of pixel in the reaction product part
center_thresh (float): threshold for the beam part
err_thresh (float): threshold for average distance to the fit
spread_thresh (float): threshold for x,y spread out

AveDist(x,y,k,b): calculate the average distance from (x,y) to a straight line with (k,b) parameters.
x (numpy float array): the x positions
y (numpy float array): the y positions
k (float): the slope of the line
b (float): the y-intercept of the line
return (float): average distance from (x,y) to the line (k,b)
r2(x,y,k,b): just to calculate the r2 score of the fitting
parameters are the same to function above
return (float): r2 score
VertexPos(fits,y0): using all fitting results and the y position from the right most tip point to estimate the vertex position
The function divide the calculation to 2 scenarios. 1. you have 2 or 3 fitted lines, then you just pick the parameters of the first two lines for the calculation. 2. if you have only 1 line and this one will not be you center line (because of previous fitting condition), you assume the center line is straight on y0.
fits ([int,float,float,float]*3): fit results for three parts of the image
return (float,float): (x,y)
tbjcfit(xs,ys): use SVD to calculate the least square DISTANCE (not y) fitting
xs (numpy float array): the x positions
ys (numpy float array): the y positions
return (int,float,float,float):(number of pixels, k,b,average distance)
GetFit(image_, part_thresh=60, err_thresh =1.2,spread_thresh=6): this function extract the x,y positions of each pixel above 0 value. Then fit the x,y points using tbjcfit. The results will be filtered through a few conditions to see if the fitting is good, like if the average distance from the points to the line is within the err_thresh and if the scattered positions does give a reasonable line shape distribution.
image_ (numpy 2d uint8 array): the part of the image you want to obtain a line fitting
part_thresh (float): if the number of pixels in the image is large enough for a fitting
err_thresh (float):the average distance to the fitting line of all the points
spread_thresh (float):the threshold for requiring a spread out distributed data on either x or y axis
return (numpy 2d uint8 array): a copy of filtered image
GetLineInfo(p1,p2, L_thre = -5): calculate the length and angle between two points
p1 (float,float): the tip point
p2 (float,float): the vertex point
L_thre = -5: not used for now
GetEventInfo(points,p0): calculate the length and angle for between each pair of the tip point and the vertex point
points ((float,float)*3): the positions of the tip points
p0 (float,float): the position of the vertex point
return ((float,float)*3,float): (theta,length) for each pair, and the reaction range
Distance(contours,n1,n2): calculate the minimum distance between two contour
contours [numpy.array (n,1,2)]:all the contours
n1 (int): index of the first contour
n2 (int): index of the second contour
return (float): the minimum distance
Groups(contours): combine all adjacent contours
contours [numpy.array (n,1,2)]:all the contours
return ((float)*n, (float)*n): grouped contours
convexHull(thresh, debug_mode = 0): calculated the convexHull using the largest grouped contour
thresh (numpy 2d uint8 array): image after preliminary processing
return ((float,float)*n): the hull points
MaxEnclosedTriangle(hull): calculate the maximum enclosed triangle using the hull points
hull ((float,float)*n): the hull points
return (int, int, int): index of the hull points to form the maximum enclosed triangle
TipFinder(thresh, debug_mode = 0): return the position of the tip on the maximum enclosed triangle
thresh (numpy 2d uint8 array): image after preliminary processing
return ((float,float)*3): the position of the tip on the maximum enclosed triangle