Project: s41467-025-56140-1 | Function: parse_gcode (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Core algorithm that parses G-Code commands, extracts motion parameters (X,Y,Z,I,J), calculates distances, and handles both linear (G1) and circular (G2/G3) motion commands. This function implements the foundational step of the T-Code method by differentiating motion commands from auxiliary commands.

**KEY TERMS:** {
  "G_command_dict": "G-Code motion commands",
  "X_dist_dict, Y_dist_dict, Z_dist_dict": "coordinate distances",
  "distance_commands_dict": "parsed command distances",
  "pythag": "Pythagorean theorem for linear distance calculation",
  "find_theta": "arc angle calculation for circular movements"
}

**CONTEXT CODE:**     # accel = acceleration/ramprate
    # x = distance traveled
    t = symbols('t')
    find_t = v_0 * t + 0.5 * (accel) * t ** 2 - x  # finds time
    sol_t = solve(find_t)
    for i in range(len(sol_t)):
        try:
            sol_t[i] >= 0
            t = sol_t[i]
        except TypeError:
            check = 0
            print("error when calcuating time; might be getting an imaginary number.")
    return t

# finds the final velocity for each distance travelled
def findv(v_0, accel, x):
    from sympy import symbols, solve
    # v_0 = starting velocity
    # accel = acceleration/ramprate
    # x = distance traveled

    try:
        v = sqrt(v_0 ** 2 + 2 * accel * x)
    except TypeError:
        print("error when calcuating velocity; might be getting an imaginary number.")

    return v

# finds the time it takes to go from an initial velocity to a final velocity
def findt_using_v(v_0, v_f, accel):
    t = (v_f - v_0) / accel
    return float(t)

'''Main functions'''
## open and read in gcode txt file into a list - remove comments, spaces, random characters
def open_gcode(gcode_txt):
    gcode_list = []
    with open(gcode_txt, "r") as gcode:
        for myline in gcode:  # For each elem in the file,
            gcode_list.append(myline.strip('\n'))
        gcode_list = [x for x in gcode_list if x != ""]  # removes spaces

        gcode_list = [x for x in gcode_list if ";--" not in x]  # removes comments
        gcode_list = [x for x in gcode_list if "---" not in x]  # removes comments
        gcode.close()
        return gcode_list

## splits up gcode into directions, distances, G command type (G1, G2, G3, etc)
## create a gcode,  distance, and direction dictionary
### Parses gcode
def parse_gcode(gcode_list):
    # MASKED: Core algorithm that parses G-Code commands, extracts motion parameters (X,Y,Z,I,J), calculates distances, and handles both linear (G1) and circular (G2/G3) motion commands. This function implements the foundational step of the T-Code method by differentiating motion commands from auxiliary commands.
    raise NotImplementedError("This function is masked for testing purposes.")

## Combines "like" gcode lines into a continuous path (used to create final gcode and acceleration path)
def condense_gcode(resync_number, resync_type, distance_commands_dict, G_command_dict, All_var_dict, X_dist_dict,Y_dist_dict, Z_dist_dict, I_dist_dict, J_dist_dict):
    dir_change_count = 0
    X_sum = X_dist_dict[0]
    Y_sum = Y_dist_dict[0]
    Z_sum = Z_dist_dict[0]
    I_0 = I_dist_dict[0]
    J_0 = J_dist_dict[0]

    Sum_G_command_dict = {0: G_command_dict[0]}
    Sum_var_dict = {0: All_var_dict[0]}
    Sum_coord_dict = {0: [X_dist_dict[0], Y_dist_dict[0], I_dist_dict[0], J_dist_dict[0]]}

    #### Finds initial distances....

    ### For linear moves
    if G_command_dict[0] == "G1":
        sum_distance = pythag(X_sum, Y_sum, Z_sum)

    ### For circles
    else:
        theta = find_theta(X_sum, Y_sum, I_0, J_0)
        if G_command_dict[0] == "G3":
            if theta <= 0:
                theta = 2 * np.pi - abs(theta)
        else:
            theta = find_theta(X_sum, Y_sum, I_0, J_0)
            if theta < 0:
                theta = abs(theta)
            else:
                theta = 2 * np.pi - theta

        R = pythag(I_0, J_0, 0)
        sum_distance = R * theta

    Sum_distance_dict = {0: sum_distance}

    resync_trigger_distance_dict = {}  # dictionary that keeps track of where direction changes occur (use to trigger a resync after N number of direction changes). ex: if key = 12, the direction changes between keys 12 and 13 in distance_commands_dict
    direction_change_dict = {}  # keeps track of direction changes

    command_count = 0
    i = 0  # count for number of times a distance command is used
    for j in range(len(distance_commands_dict)):
        type_check = type(distance_commands_dict[j])
        if type_check == str:
            command_count += 1

        if type_check != str and i < len(G_command_dict) - 1:
            i += 1
            current_G_command = G_command_dict[i]
            current_var = All_var_dict[i]
            ## Combines "like" gcode lines into a continuous path
            # for circular moves, slope = radius
            if G_command_dict[i] == G_command_dict[i - 1] and All_var_dict[i] == All_var_dict[i - 1] and slope_dict[i] == slope_dict[i - 1]:
                # '''G1 Commands'''
                if current_G_command == "G1":
                    X_sum += X_dist_dict[i]
                    Y_sum += Y_dist_dict[i]
                    Z_sum += Z_dist_dict[i]

                # '''G2/G3 Commands'''
                elif (round(I_dist_dict[i], 9) == round(I_dist_dict[i - 1] - X_dist_dict[i - 1]), 9) and (
                        round(J_dist_dict[i], 9) == round(J_dist_dict[i - 1] - Y_dist_dict[i - 1]), 9):

                    X_sum += X_dist_dict[i]
                    Y_sum += Y_dist_dict[i]

                    if round(X_sum, 9) == 0:
                        X_sum = 0
                    if round(Y_sum, 9) == 0:
                        Y_sum = 0


                else:  # if it is not a continuous circle

                    dir_change_count += 1

                    X_sum = X_dist_dict[i]
                    Y_sum = Y_dist_dict[i]
                    Z_sum = Z_dist_dict[i]
                    I_0 = I_dist_dict[i]  # I value is always referenced from starting point
                    J_0 = J_dist_dict[i]  # J value is always referenced from starting point

                    if resync_type == 'direction-based' and dir_change_count % resync_number == 0:
                        resync_trigger_distance_dict[dir_change_count - 1] = j

            else:
                dir_change_count += 1
                X_sum = X_dist_dict[i]
                Y_sum = Y_dist_dict[i]
                Z_sum = Z_dist_dict[i]
                I_0 = I_dist_dict[i]  # I value is always referenced from starting point
                J_0 = J_dist_dict[i]  # J value is always referenced from starting point

                if resync_type == 'direction-based' and dir_change_count % resync_number == 0:
                    resync_trigger_distance_dict[dir_change_count - 1] = j


Complete the function implementation replacing "raise NotImplementedError".