Ruff and Flake8 code refactoring and linting

This commit is contained in:
Félix Boisselier
2024-04-13 13:12:43 +02:00
parent 41590be745
commit ef006dbd1e
6 changed files with 905 additions and 483 deletions

View File

@@ -9,25 +9,22 @@
# Use the provided Shake&Tune macros instead!
import glob
import optparse
import os
import time
import glob
import sys
import shutil
import sys
import tarfile
import time
from datetime import datetime
#################################################################################################################
RESULTS_FOLDER = os.path.expanduser('~/printer_data/config/K-ShakeTune_results')
KLIPPER_FOLDER = os.path.expanduser('~/klipper')
#################################################################################################################
from analyze_axesmap import axesmap_calibration
from graph_belts import belts_calibration
from graph_shaper import shaper_calibration
from graph_vibrations import vibrations_profile
from analyze_axesmap import axesmap_calibration
RESULTS_FOLDER = os.path.expanduser('~/printer_data/config/K-ShakeTune_results')
KLIPPER_FOLDER = os.path.expanduser('~/klipper')
RESULTS_SUBFOLDERS = ['belts', 'inputshaper', 'vibrations']
@@ -53,10 +50,10 @@ def create_belts_graph(keep_csv):
globbed_files = glob.glob('/tmp/raw_data_axis*.csv')
if not globbed_files:
print("No CSV files found in the /tmp folder to create the belt graphs!")
print('No CSV files found in the /tmp folder to create the belt graphs!')
sys.exit(1)
if len(globbed_files) < 2:
print("Not enough CSV files found in the /tmp folder. Two files are required for the belt graphs!")
print('Not enough CSV files found in the /tmp folder. Two files are required for the belt graphs!')
sys.exit(1)
sorted_files = sorted(globbed_files, key=os.path.getmtime, reverse=True)
@@ -65,12 +62,12 @@ def create_belts_graph(keep_csv):
# Wait for the file handler to be released by Klipper
while is_file_open(filename):
time.sleep(2)
# Extract the tested belt from the filename and rename/move the CSV file to the result folder
belt = os.path.basename(filename).split('_')[3].split('.')[0].upper()
new_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[0], f'belt_{current_date}_{belt}.csv')
shutil.move(filename, new_file)
os.sync() # Sync filesystem to avoid problems
os.sync() # Sync filesystem to avoid problems
# Save the file path for later
lognames.append(new_file)
@@ -78,12 +75,12 @@ def create_belts_graph(keep_csv):
# Wait for the file handler to be released by the move command
while is_file_open(new_file):
time.sleep(2)
# Generate the belts graph and its name
fig = belts_calibration(lognames, KLIPPER_FOLDER)
png_filename = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[0], f'belts_{current_date}.png')
fig.savefig(png_filename, dpi=150)
# Remove the CSV files if the user don't want to keep them
if not keep_csv:
for csv in lognames:
@@ -99,7 +96,7 @@ def create_shaper_graph(keep_csv, max_smoothing, scv):
# Get all the files and sort them based on last modified time to select the most recent one
globbed_files = glob.glob('/tmp/raw_data*.csv')
if not globbed_files:
print("No CSV files found in the /tmp folder to create the input shaper graphs!")
print('No CSV files found in the /tmp folder to create the input shaper graphs!')
sys.exit(1)
sorted_files = sorted(globbed_files, key=os.path.getmtime, reverse=True)
@@ -108,17 +105,17 @@ def create_shaper_graph(keep_csv, max_smoothing, scv):
# Wait for the file handler to be released by Klipper
while is_file_open(filename):
time.sleep(2)
# Extract the tested axis from the filename and rename/move the CSV file to the result folder
axis = os.path.basename(filename).split('_')[3].split('.')[0].upper()
new_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[1], f'resonances_{current_date}_{axis}.csv')
shutil.move(filename, new_file)
os.sync() # Sync filesystem to avoid problems
os.sync() # Sync filesystem to avoid problems
# Wait for the file handler to be released by the move command
while is_file_open(new_file):
time.sleep(2)
# Generate the shaper graph and its name
fig = shaper_calibration([new_file], KLIPPER_FOLDER, max_smoothing=max_smoothing, scv=scv)
png_filename = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[1], f'resonances_{current_date}_{axis}.png')
@@ -128,7 +125,7 @@ def create_shaper_graph(keep_csv, max_smoothing, scv):
if not keep_csv:
if os.path.exists(new_file):
os.remove(new_file)
return axis
@@ -138,10 +135,10 @@ def create_vibrations_graph(accel, kinematics, chip_name, keep_csv):
globbed_files = glob.glob(f'/tmp/{chip_name}-*.csv')
if not globbed_files:
print("No CSV files found in the /tmp folder to create the vibration graphs!")
print('No CSV files found in the /tmp folder to create the vibration graphs!')
sys.exit(1)
if len(globbed_files) < 3:
print("Not enough CSV files found in the /tmp folder. At least 3 files are required for the vibration graphs!")
print('Not enough CSV files found in the /tmp folder. At least 3 files are required for the vibration graphs!')
sys.exit(1)
for filename in globbed_files:
@@ -165,10 +162,12 @@ def create_vibrations_graph(accel, kinematics, chip_name, keep_csv):
fig = vibrations_profile(lognames, KLIPPER_FOLDER, kinematics, accel)
png_filename = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[2], f'vibrations_{current_date}.png')
fig.savefig(png_filename, dpi=150)
# Archive all the csv files in a tarball in case the user want to keep them
if keep_csv:
with tarfile.open(os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[2], f'vibrations_{current_date}.tar.gz'), 'w:gz') as tar:
with tarfile.open(
os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[2], f'vibrations_{current_date}.tar.gz'), 'w:gz'
) as tar:
for csv_file in lognames:
tar.add(csv_file, arcname=os.path.basename(csv_file), recursive=False)
@@ -187,7 +186,7 @@ def find_axesmap(accel, chip_name):
globbed_files = glob.glob(f'/tmp/{chip_name}-*.csv')
if not globbed_files:
print("No CSV files found in the /tmp folder to analyze and find the axes_map!")
print('No CSV files found in the /tmp folder to analyze and find the axes_map!')
sys.exit(1)
sorted_files = sorted(globbed_files, key=os.path.getmtime, reverse=True)
@@ -213,6 +212,7 @@ def get_old_files(folder, extension, limit):
files.sort(key=lambda x: os.path.getmtime(x), reverse=True)
return files[limit:]
def clean_files(keep_results):
# Define limits based on STORE_RESULTS
keep1 = keep_results + 1
@@ -225,16 +225,18 @@ def clean_files(keep_results):
# Remove the old belt files
for old_file in old_belts_files:
file_date = "_".join(os.path.splitext(os.path.basename(old_file))[0].split('_')[1:3])
file_date = '_'.join(os.path.splitext(os.path.basename(old_file))[0].split('_')[1:3])
for suffix in ['A', 'B']:
csv_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[0], f'belt_{file_date}_{suffix}.csv')
if os.path.exists(csv_file):
os.remove(csv_file)
os.remove(old_file)
# Remove the old shaper files
for old_file in old_inputshaper_files:
csv_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[1], os.path.splitext(os.path.basename(old_file))[0] + ".csv")
csv_file = os.path.join(
RESULTS_FOLDER, RESULTS_SUBFOLDERS[1], os.path.splitext(os.path.basename(old_file))[0] + '.csv'
)
if os.path.exists(csv_file):
os.remove(csv_file)
os.remove(old_file)
@@ -242,44 +244,89 @@ def clean_files(keep_results):
# Remove the old vibrations files
for old_file in old_speed_vibr_files:
os.remove(old_file)
tar_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[2], os.path.splitext(os.path.basename(old_file))[0] + ".tar.gz")
tar_file = os.path.join(
RESULTS_FOLDER, RESULTS_SUBFOLDERS[2], os.path.splitext(os.path.basename(old_file))[0] + '.tar.gz'
)
if os.path.exists(tar_file):
os.remove(tar_file)
def main():
# Parse command-line arguments
usage = "%prog [options] <logs>"
usage = '%prog [options] <logs>'
opts = optparse.OptionParser(usage)
opts.add_option("-t", "--type", type="string", dest="type",
default=None, help="type of output graph to produce")
opts.add_option("--accel", type="int", default=None, dest="accel_used",
help="acceleration used during the vibration macro or axesmap macro")
opts.add_option("--axis_name", type="string", default=None, dest="axis_name",
help="axis tested during the vibration macro")
opts.add_option("--chip_name", type="string", default="adxl345", dest="chip_name",
help="accelerometer chip name in klipper used during the vibration macro or the axesmap macro")
opts.add_option("-n", "--keep_results", type="int", default=3, dest="keep_results",
help="number of results to keep in the result folder after each run of the script")
opts.add_option("-c", "--keep_csv", action="store_true", default=False, dest="keep_csv",
help="weither or not to keep the CSV files alongside the PNG graphs image results")
opts.add_option("--scv", "--square_corner_velocity", type="float", dest="scv", default=5.,
help="square corner velocity used to compute max accel for axis shapers graphs")
opts.add_option("--max_smoothing", type="float", dest="max_smoothing", default=None,
help="maximum shaper smoothing to allow")
opts.add_option("-m", "--kinematics", type="string", dest="kinematics",
default="cartesian", help="machine kinematics configuration used for the vibrations graphs")
options, args = opts.parse_args()
opts.add_option('-t', '--type', type='string', dest='type', default=None, help='type of output graph to produce')
opts.add_option(
'--accel',
type='int',
default=None,
dest='accel_used',
help='acceleration used during the vibration macro or axesmap macro',
)
opts.add_option(
'--axis_name', type='string', default=None, dest='axis_name', help='axis tested during the vibration macro'
)
opts.add_option(
'--chip_name',
type='string',
default='adxl345',
dest='chip_name',
help='accelerometer chip name in klipper used during the vibration macro or the axesmap macro',
)
opts.add_option(
'-n',
'--keep_results',
type='int',
default=3,
dest='keep_results',
help='number of results to keep in the result folder after each run of the script',
)
opts.add_option(
'-c',
'--keep_csv',
action='store_true',
default=False,
dest='keep_csv',
help='weither or not to keep the CSV files alongside the PNG graphs image results',
)
opts.add_option(
'--scv',
'--square_corner_velocity',
type='float',
dest='scv',
default=5.0,
help='square corner velocity used to compute max accel for axis shapers graphs',
)
opts.add_option(
'--max_smoothing', type='float', dest='max_smoothing', default=None, help='maximum shaper smoothing to allow'
)
opts.add_option(
'-m',
'--kinematics',
type='string',
dest='kinematics',
default='cartesian',
help='machine kinematics configuration used for the vibrations graphs',
)
options, _ = opts.parse_args()
if options.type is None:
opts.error("You must specify the type of output graph you want to produce (option -t)")
elif options.type.lower() is None or options.type.lower() not in ['belts', 'shaper', 'vibrations', 'axesmap', 'clean']:
opts.error("Type of output graph need to be in the list of 'belts', 'shaper', 'vibrations', 'axesmap' or 'clean'")
opts.error('You must specify the type of output graph you want to produce (option -t)')
elif options.type.lower() is None or options.type.lower() not in [
'belts',
'shaper',
'vibrations',
'axesmap',
'clean',
]:
opts.error(
"Type of output graph need to be in the list of 'belts', 'shaper', 'vibrations', 'axesmap' or 'clean'"
)
else:
graph_mode = options.type
if graph_mode.lower() == "vibrations" and options.kinematics not in ["cartesian", "corexy"]:
opts.error("Only Cartesian and CoreXY kinematics are supported by this tool at the moment!")
if graph_mode.lower() == 'vibrations' and options.kinematics not in ['cartesian', 'corexy']:
opts.error('Only Cartesian and CoreXY kinematics are supported by this tool at the moment!')
# Check if results folders are there or create them before doing anything else
for result_subfolder in RESULTS_SUBFOLDERS:
@@ -289,22 +336,35 @@ def main():
if graph_mode.lower() == 'belts':
create_belts_graph(keep_csv=options.keep_csv)
print(f"Belt graph created. You will find the results in {RESULTS_FOLDER}/{RESULTS_SUBFOLDERS[0]}")
print(f'Belt graph created. You will find the results in {RESULTS_FOLDER}/{RESULTS_SUBFOLDERS[0]}')
elif graph_mode.lower() == 'shaper':
axis = create_shaper_graph(keep_csv=options.keep_csv, max_smoothing=options.max_smoothing, scv=options.scv)
print(f"{axis} input shaper graph created. You will find the results in {RESULTS_FOLDER}/{RESULTS_SUBFOLDERS[1]}")
print(
f'{axis} input shaper graph created. You will find the results in {RESULTS_FOLDER}/{RESULTS_SUBFOLDERS[1]}'
)
elif graph_mode.lower() == 'vibrations':
create_vibrations_graph(accel=options.accel_used, kinematics=options.kinematics, chip_name=options.chip_name, keep_csv=options.keep_csv)
print(f"Vibrations graph created. You will find the results in {RESULTS_FOLDER}/{RESULTS_SUBFOLDERS[2]}")
create_vibrations_graph(
accel=options.accel_used,
kinematics=options.kinematics,
chip_name=options.chip_name,
keep_csv=options.keep_csv,
)
print(f'Vibrations graph created. You will find the results in {RESULTS_FOLDER}/{RESULTS_SUBFOLDERS[2]}')
elif graph_mode.lower() == 'axesmap':
print(f"WARNING: AXES_MAP_CALIBRATION is currently very experimental and may produce incorrect results... Please validate the output!")
print(
'WARNING: AXES_MAP_CALIBRATION is currently very experimental and may produce incorrect results... Please validate the output!'
)
find_axesmap(accel=options.accel_used, chip_name=options.chip_name)
elif graph_mode.lower() == 'clean':
print(f"Cleaning output folder to keep only the last {options.keep_results} results...")
print(f'Cleaning output folder to keep only the last {options.keep_results} results...')
clean_files(keep_results=options.keep_results)
if options.keep_csv is False and graph_mode.lower() != 'clean':
print(f"Deleting raw CSV files... If you want to keep them, use the --keep_csv option!")
print('Deleting raw CSV files... If you want to keep them, use the --keep_csv option!')
if __name__ == '__main__':