From 4336cf59cb6b53afa004f6f35c1605a58326b14a Mon Sep 17 00:00:00 2001 From: Alex Liberzon Date: Thu, 21 Mar 2024 21:54:05 +0200 Subject: [PATCH 1/6] trying to update gui with the latest openpiv 0.25.0 --- .gitignore | 5 +++++ openpivgui/MultiProcessing.py | 11 +++++++---- openpivgui/OpenPivGui.py | 4 ++-- openpivgui/PreProcessing.py | 3 +-- setup.py | 5 ++--- 5 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..49302188 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ + +*.pyc +dist/* +openpivgui.egg-info/* +.vscode/* diff --git a/openpivgui/MultiProcessing.py b/openpivgui/MultiProcessing.py index 1733c5f4..f510b091 100755 --- a/openpivgui/MultiProcessing.py +++ b/openpivgui/MultiProcessing.py @@ -230,8 +230,11 @@ def smoothn(u, s): # validating first pass mask = np.full_like(x, 0) + u = np.ma.copy(u) + v = np.ma.copy(v) + if self.parameter['fp_vld_global_threshold']: - u, v, Mask = piv_vld.global_val( + Mask = piv_vld.global_val( u, v, u_thresholds=(self.parameter['fp_MinU'], self.parameter['fp_MaxU']), @@ -241,7 +244,7 @@ def smoothn(u, s): mask += Mask if self.parameter['fp_local_med']: - u, v, Mask = piv_vld.local_median_val( + Mask = piv_vld.local_median_val( u, v, u_threshold=self.parameter['fp_local_med'], v_threshold=self.parameter['fp_local_med'], @@ -250,7 +253,7 @@ def smoothn(u, s): if self.parameter['adv_repl']: u, v = piv_flt.replace_outliers( - u, v, + u, v, mask, method=self.parameter['adv_repl_method'], max_iter=self.parameter['adv_repl_iter'], kernel_size=self.parameter['adv_repl_kernel']) @@ -293,7 +296,7 @@ def smoothn(u, s): sizeX = corr_window # translate settings to windef settings object - piv_wdf_settings = piv_wdf.Settings() + piv_wdf_settings = piv_wdf.PIVSettings() piv_wdf_settings.correlation_method = \ self.parameter['corr_method'] piv_wdf_settings.normalized_correlation = \ diff --git a/openpivgui/OpenPivGui.py b/openpivgui/OpenPivGui.py index 709d7383..10186153 100755 --- a/openpivgui/OpenPivGui.py +++ b/openpivgui/OpenPivGui.py @@ -38,7 +38,7 @@ import re import os -__version__ = '0.4.14' +__version__ = '0.4.15' __licence__ = ''' This program is free software: you can redistribute it and/or modify @@ -598,7 +598,7 @@ def selection(self, num): def calculate_invalid_vectors(self): try: self.get_settings() - data = self.load_pandas(self.p['fnames'][self.index] + data = self.load_pandas(self.p['fnames'][self.index]) data=data.to_numpy().astype(float) try: invalid=data[:, 4].astype('bool') diff --git a/openpivgui/PreProcessing.py b/openpivgui/PreProcessing.py index e72211fa..b1f9c1c3 100755 --- a/openpivgui/PreProcessing.py +++ b/openpivgui/PreProcessing.py @@ -3,8 +3,7 @@ """Post Processing for OpenPIVGui.""" -from skimage import exposure, filters, util -import openpiv.preprocess as piv_pre +from skimage import util import openpiv.tools as piv_tls import numpy as np diff --git a/setup.py b/setup.py index d373f6b2..6bd3ae44 100644 --- a/setup.py +++ b/setup.py @@ -1,13 +1,12 @@ import setuptools -from glob import glob with open("README.md", "r") as fh: long_description = fh.read() setuptools.setup( name="openpivgui", - version="0.4.14", - install_requires=['OpenPiv==0.23.8', 'pandas'], + version="0.4.15", + install_requires=['OpenPiv', 'pandas'], author="P. Vennemann and contributors.", author_email="vennemann@fh-muenster.de", description="A simple GUI for Open PIV.", From 1398cac7ddb5817f89c4ed0e785974e261110b76 Mon Sep 17 00:00:00 2001 From: Alex Liberzon Date: Fri, 19 Apr 2024 00:37:34 +0300 Subject: [PATCH 2/6] updated to use modern openpiv. works till postprocessing --- build/lib/openpivgui/OpenPivGui.py | 5 +++-- openpivgui/MultiProcessing.py | 15 ++++++++------- openpivgui/OpenPivGui.py | 8 ++++++-- setup.py | 2 +- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/build/lib/openpivgui/OpenPivGui.py b/build/lib/openpivgui/OpenPivGui.py index 02245c0b..1e1b7b26 100644 --- a/build/lib/openpivgui/OpenPivGui.py +++ b/build/lib/openpivgui/OpenPivGui.py @@ -13,7 +13,7 @@ from openpivgui.CreateToolTip import CreateToolTip from openpivgui.OpenPivParams import OpenPivParams import openpivgui.AddInHandler as AddInHandler -from scipy.ndimage.filters import gaussian_filter, gaussian_laplace +from scipy.ndimage import gaussian_filter, gaussian_laplace from matplotlib.figure import Figure as Fig from matplotlib.backend_bases import key_press_handler from matplotlib.backends.backend_tkagg import ( @@ -222,6 +222,7 @@ def processing(self): (os.cpu_count() - cpu_count), os.cpu_count())) mp.run(func=mp.process, n_cpus=cpu_count) + # mp.run(func=mp.process, n_cpus=cpu_count) # update file list with result vector files: self.tkvars['fnames'].set(return_fnames) @@ -531,7 +532,7 @@ def __init_buttons(self): piv = ttk.Menubutton(f, text='Analysis') options2 = tk.Menu(piv, tearoff=0) piv.config(menu=options2) - options2.add_command(label='Algorithms\Calibration', + options2.add_command(label='Algorithms/Calibration', command=lambda: self.selection(2)) options2.add_command(label='Windowing', command=lambda: self.selection(3)) diff --git a/openpivgui/MultiProcessing.py b/openpivgui/MultiProcessing.py index f510b091..2bc92df1 100755 --- a/openpivgui/MultiProcessing.py +++ b/openpivgui/MultiProcessing.py @@ -12,9 +12,10 @@ import openpiv.filters as piv_flt import openpiv.validation as piv_vld import openpiv.windef as piv_wdf -import openpiv.pyprocess as piv_prc -import openpiv.preprocess as piv_pre import openpiv.tools as piv_tls + + + __licence__ = ''' This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -229,7 +230,7 @@ def smoothn(u, s): overlap_0) # validating first pass - mask = np.full_like(x, 0) + mask = np.zeros_like(x, dtype=bool) u = np.ma.copy(u) v = np.ma.copy(v) @@ -325,7 +326,7 @@ def smoothn(u, s): # validate other passes if self.parameter['sp_vld_global_threshold']: - u, v, Mask = piv_vld.global_val( + Mask = piv_vld.global_val( u, v, u_thresholds=(self.parameter['sp_MinU'], self.parameter['sp_MaxU']), @@ -334,13 +335,13 @@ def smoothn(u, s): mask += Mask # consolidate effects of mask if self.parameter['sp_vld_global_threshold']: - u, v, Mask = piv_vld.global_std( + Mask = piv_vld.global_std( u, v, std_threshold=self.parameter['sp_std_threshold']) mask += Mask if self.parameter['sp_local_med_validation']: - u, v, Mask = piv_vld.local_median_val( + Mask = piv_vld.local_median_val( u, v, u_threshold=self.parameter['sp_local_med'], v_threshold=self.parameter['sp_local_med'], @@ -349,7 +350,7 @@ def smoothn(u, s): if self.parameter['adv_repl']: u, v = piv_flt.replace_outliers( - u, v, + u, v, mask, method=self.parameter['adv_repl_method'], max_iter=self.parameter['adv_repl_iter'], kernel_size=self.parameter['adv_repl_kernel']) diff --git a/openpivgui/OpenPivGui.py b/openpivgui/OpenPivGui.py index 10186153..fa57308c 100755 --- a/openpivgui/OpenPivGui.py +++ b/openpivgui/OpenPivGui.py @@ -13,7 +13,7 @@ from openpivgui.CreateToolTip import CreateToolTip from openpivgui.OpenPivParams import OpenPivParams import openpivgui.AddInHandler as AddInHandler -from scipy.ndimage.filters import gaussian_filter, gaussian_laplace +from scipy.ndimage import gaussian_filter, gaussian_laplace from matplotlib.figure import Figure as Fig from matplotlib.backend_bases import key_press_handler from matplotlib.backends.backend_tkagg import ( @@ -38,6 +38,10 @@ import re import os +import multiprocessing, logging +logger = multiprocessing.log_to_stderr() +logger.setLevel(multiprocessing.SUBDEBUG) + __version__ = '0.4.15' __licence__ = ''' @@ -533,7 +537,7 @@ def __init_buttons(self): piv = ttk.Menubutton(f, text='Analysis') options2 = tk.Menu(piv, tearoff=0) piv.config(menu=options2) - options2.add_command(label='Algorithms\Calibration', + options2.add_command(label='Algorithms/Calibration', command=lambda: self.selection(2)) options2.add_command(label='Windowing', command=lambda: self.selection(3)) diff --git a/setup.py b/setup.py index 6bd3ae44..7e12e2d7 100644 --- a/setup.py +++ b/setup.py @@ -21,5 +21,5 @@ "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: OS Independent", ], - python_requires='>=3.0', + python_requires='>=3.10', ) From a891fda09a1323de28c89101e977decfc02eae54 Mon Sep 17 00:00:00 2001 From: Alex Liberzon Date: Fri, 19 Apr 2024 16:37:04 +0300 Subject: [PATCH 3/6] updated the gui PostProcessing with the arrays for openpiv since some version of openpiv the local median is using 2D arrays, so the replace outliers and and smoothing the smoothing seems to be too long, probably one needs Cython or manage to compile it for any platform. --- .gitignore | 6 ++++ openpivgui/PostProcessing.py | 54 +++++++++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 49302188..2e668363 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,9 @@ dist/* openpivgui.egg-info/* .vscode/* +build/* +docs/_build/* +docs/_build/doctrees/* +docs/_build/html/* +docs/_build/html/_static/* +dist/* diff --git a/openpivgui/PostProcessing.py b/openpivgui/PostProcessing.py index 28da2814..a4e0bdb7 100644 --- a/openpivgui/PostProcessing.py +++ b/openpivgui/PostProcessing.py @@ -55,8 +55,8 @@ def sig2noise(self): result_fnames = [] for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) - u, v, mask = piv_vld.sig2noise_val( - data[:, 2], data[:, 3], data[:, 5], + mask = piv_vld.sig2noise_val( + data[:, 5], threshold=self.p['sig2noise_threshold']) save_fname = create_save_vec_fname( @@ -65,7 +65,8 @@ def sig2noise(self): save(data[:, 0], data[:, 1], - u, v, + data[:, 2], + data[:, 3], data[:, 4] + mask, sig2noise=data[:, 5], filename=save_fname, @@ -84,15 +85,18 @@ def global_std(self): result_fnames = [] for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) - u, v, mask = piv_vld.global_std( + + mask = piv_vld.global_std( data[:, 2], data[:, 3], std_threshold=self.p['global_std_threshold']) + save_fname = create_save_vec_fname( path=f, postfix='_std_thrhld') save(data[:, 0], data[:, 1], - u, v, + data[:, 2], + data[:, 3], data[:, 4] + mask, data[:, 5], save_fname, @@ -110,16 +114,19 @@ def global_val(self): result_fnames = [] for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) - u, v, mask = piv_vld.global_val( + mask = piv_vld.global_val( data[:, 2], data[:, 3], u_thresholds=(self.p['MinU'], self.p['MaxU']), v_thresholds=(self.p['MinV'], self.p['MaxV'])) + save_fname = create_save_vec_fname( path=f, postfix='_glob_thrhld') + save(data[:, 0], data[:, 1], - u, v, + data[:, 2], + data[:, 3], data[:, 4] + mask, data[:, 5], save_fname, @@ -138,18 +145,25 @@ def local_median(self): result_fnames = [] for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) - u, v, mask = piv_vld.local_median_val( - data[:, 2], data[:, 3], + + u = data[:, 2].reshape(len(set(data[:,0])), len(set(data[:,1]))) + v = data[:, 3].reshape(len(set(data[:,0])), len(set(data[:,1]))) + + mask = piv_vld.local_median_val( + u, v, u_threshold=self.p['local_median_threshold'], v_threshold=self.p['local_median_threshold'], size=self.p['local_median_size']) + save_fname = create_save_vec_fname( path=f, postfix='_med_thrhld') + save(data[:, 0], data[:, 1], - u, v, - data[:, 4] + mask, + data[:, 2], + data[:, 3], + data[:, 4] + mask.flatten(), data[:, 5], save_fname, delimiter=self.delimiter) @@ -161,8 +175,16 @@ def repl_outliers(self): result_fnames = [] for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) + + shapes = (len(set(data[:,0])), len(set(data[:,1]))) + + u = data[:, 2].reshape(shapes) + v = data[:, 3].reshape(shapes) + flags = data[:, 4].reshape(shapes).astype(bool) + u, v = piv_flt.replace_outliers( - np.array([data[:, 2]]), np.array([data[:, 3]]), + u, v, + flags, # <- flags for outliers, mask for the static image mask method=self.p['repl_method'], max_iter=self.p['repl_iter'], kernel_size=self.p['repl_kernel']) @@ -171,7 +193,8 @@ def repl_outliers(self): postfix='_repl') save(data[:, 0], data[:, 1], - u, v, + u.flatten(), + v.flatten(), # <- holes filled version data[:, 4], data[:, 5], save_fname, @@ -184,6 +207,11 @@ def smoothn_r(self): result_fnames = [] for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) + shapes = (len(set(data[:,0])), len(set(data[:,1]))) + + u = data[:, 2].reshape(shapes) + v = data[:, 3].reshape(shapes) + u, _, _, _ = piv_smt.smoothn( data[:, 2], s=self.p['smoothn_val'], isrobust=self.p['robust']) v, _, _, _ = piv_smt.smoothn( From 5ad1d6847ccba5328f1d224bb7d68f3adc310d3d Mon Sep 17 00:00:00 2001 From: eguvep Date: Fri, 19 Apr 2024 13:38:38 +0000 Subject: [PATCH 4/6] Automated autopep8 fixes. --- openpivgui/MultiProcessing.py | 1 - openpivgui/OpenPivGui.py | 357 +++++++++++++++++----------------- openpivgui/PostProcessing.py | 34 ++-- 3 files changed, 196 insertions(+), 196 deletions(-) diff --git a/openpivgui/MultiProcessing.py b/openpivgui/MultiProcessing.py index 2bc92df1..96929eac 100755 --- a/openpivgui/MultiProcessing.py +++ b/openpivgui/MultiProcessing.py @@ -15,7 +15,6 @@ import openpiv.tools as piv_tls - __licence__ = ''' This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/openpivgui/OpenPivGui.py b/openpivgui/OpenPivGui.py index fa57308c..4572d84d 100755 --- a/openpivgui/OpenPivGui.py +++ b/openpivgui/OpenPivGui.py @@ -38,7 +38,8 @@ import re import os -import multiprocessing, logging +import multiprocessing +import logging logger = multiprocessing.log_to_stderr() logger.setLevel(multiprocessing.SUBDEBUG) @@ -225,7 +226,7 @@ def processing(self): 'or deselect >manually select cores<.') print('Cores left: {} of {}.'.format( - (os.cpu_count() - cpu_count), os.cpu_count())) + (os.cpu_count() - cpu_count), os.cpu_count())) mp.run(func=mp.process, n_cpus=cpu_count) @@ -257,7 +258,7 @@ def start_postprocessing(self): check_processing(self) check_postprocessing(self.p) # simple error checking self.postprocessing_thread = threading.Thread( - target=self.postprocessing) + target=self.postprocessing) self.postprocessing_thread.start() except Exception as e: print('Post-processing thread stopped. ' + str(e)) @@ -283,32 +284,32 @@ def postprocessing(self): if self.p[str(boolean_var)]: post_proc = PostProcessing(self.p) self.tkvars['fnames'].set( - self.postprocessing_methods[func][2] - (self, post_proc.delimiter)) + self.postprocessing_methods[func][2] + (self, post_proc.delimiter)) # standard deviation validation self.get_settings() if self.p['vld_sig2noise']: self.tkvars['fnames'].set( - PostProcessing(self.p).sig2noise()) + PostProcessing(self.p).sig2noise()) # standard deviation validation self.get_settings() if self.p['vld_global_std']: self.tkvars['fnames'].set( - PostProcessing(self.p).global_std()) + PostProcessing(self.p).global_std()) # global threshold validation self.get_settings() if self.p['vld_global_thr']: self.tkvars['fnames'].set( - PostProcessing(self.p).global_val()) + PostProcessing(self.p).global_val()) # local median validation self.get_settings() if self.p['vld_local_med']: self.tkvars['fnames'].set( - PostProcessing(self.p).local_median()) + PostProcessing(self.p).local_median()) # log validation parameters if (True in boolean_vars_of_add_ins or @@ -335,20 +336,20 @@ def postprocessing(self): if self.p[str(boolean_var)]: post_proc = PostProcessing(self.p) self.tkvars['fnames'].set( - self.postprocessing_methods[func][2] - (self, post_proc.delimiter)) + self.postprocessing_methods[func][2] + (self, post_proc.delimiter)) # post processing self.get_settings() if self.p['repl']: self.tkvars['fnames'].set( - PostProcessing(self.p).repl_outliers()) + PostProcessing(self.p).repl_outliers()) # smooth post processing self.get_settings() if self.p['smoothn']: self.tkvars['fnames'].set( - PostProcessing(self.p).smoothn_r()) + PostProcessing(self.p).smoothn_r()) # average all ressults # self.get_settings() @@ -440,13 +441,13 @@ def __init_fig_canvas(self, mother_frame): expand='True') self.fig_canvas = FigureCanvasTkAgg( - self.fig, master=self.fig_frame) + self.fig, master=self.fig_frame) self.fig_canvas.draw() self.fig_canvas.get_tk_widget().pack( - side='left', - fill='x', - expand='True') + side='left', + fill='x', + expand='True') fig_toolbar = NavigationToolbar2Tk(self.fig_canvas, self.fig_frame) fig_toolbar.update() @@ -507,7 +508,7 @@ def __init_buttons(self): options.add_separator() options.add_command(label='Save session', command=lambda: self.p.dump_settings( - filedialog.asksaveasfilename())) + filedialog.asksaveasfilename())) options.add_command(label='Load session', command=self.load_settings) options.add_command(label='Reset session', command=self.reset_params) options.add_separator() @@ -562,9 +563,9 @@ def __init_buttons(self): options4 = tk.Menu(plot, tearoff=0) plot.config(menu=options4) options4.add_command( - label='Plotting', command=lambda: self.selection(7)) + label='Plotting', command=lambda: self.selection(7)) options4.add_command( - label='Modify Appearance', command=lambda: self.selection(8)) + label='Modify Appearance', command=lambda: self.selection(8)) plot.pack(side='left', fill='x') lab_func = ttk.Menubutton(f, text='Lab Book') options6 = tk.Menu(lab_func, tearoff=0) @@ -578,9 +579,9 @@ def __init_buttons(self): usage_func.config(menu=options7) options7.add_command(label='Usage', command=lambda: messagebox.showinfo( - title='Help', - message=inspect.cleandoc( - OpenPivGui.__doc__))) + title='Help', + message=inspect.cleandoc( + OpenPivGui.__doc__))) usage_func.pack(side='left', fill='x') web_func = ttk.Menubutton(f, text='Web') @@ -603,16 +604,16 @@ def calculate_invalid_vectors(self): try: self.get_settings() data = self.load_pandas(self.p['fnames'][self.index]) - data=data.to_numpy().astype(float) + data = data.to_numpy().astype(float) try: - invalid=data[:, 4].astype('bool') - except: - invalid=np.asarray([True for i in range(len(data))]) + invalid = data[:, 4].astype('bool') + except BaseException: + invalid = np.asarray([True for i in range(len(data))]) print('No typevectors found') - invalid=np.count_nonzero(invalid) - percent=_round(((invalid / len(data[:, 0])) * 100), 4) - message=('Percent invalid vectors for result index {}: {}%' + invalid = np.count_nonzero(invalid) + percent = _round(((invalid / len(data[:, 0])) * 100), 4) + message = ('Percent invalid vectors for result index {}: {}%' .format(self.index, percent)) if self.p['pop_up_info']: @@ -627,11 +628,11 @@ def calculate_invalid_vectors(self): def reset_params(self): """Reset parameters to default values.""" - answer=messagebox.askyesno( - title='Reset session', - message='Reset all parameters to default values?') + answer = messagebox.askyesno( + title='Reset session', + message='Reset all parameters to default values?') if answer: - self.p=OpenPivParams() + self.p = OpenPivParams() self.set_settings() def readme(self): @@ -640,30 +641,30 @@ def readme(self): def delete_files(self): """Delete files currently listed in the file list.""" - answer=messagebox.askyesno( - title='Delete files', - message='Are you sure you want to delete selected files?') + answer = messagebox.askyesno( + title='Delete files', + message='Are you sure you want to delete selected files?') if answer: - files=self.p['fnames'][:] + files = self.p['fnames'][:] for f in files: os.remove(f) self.navigate('back') def move_files(self): """Move files to a new place.""" - files=self.p['fnames'][:] - dir=filedialog.askdirectory(mustexist=False) + files = self.p['fnames'][:] + dir = filedialog.askdirectory(mustexist=False) if len(dir) > 0: if not os.path.exists(dir): os.mkdir(dir) for src in files: - dst=dir + os.path.sep + os.path.basename(src) + dst = dir + os.path.sep + os.path.basename(src) shutil.move(src, dst) self.navigate('back') def load_settings(self): """Load settings from a JSON file.""" - settings=filedialog.askopenfilename() + settings = filedialog.askopenfilename() if len(settings) > 0: self.p.load_settings(settings) self.set_settings() @@ -687,64 +688,64 @@ def load_pandas(self, fname): In case of an error, the errormessage is returned (str). """ - ext=fname.split('.')[-1] + ext = fname.split('.')[-1] if ext in ['txt', 'dat', 'jvc', 'vec', 'csv']: - file=pd.read_csv(fname) + file = pd.read_csv(fname) for column in file: for line in file[column]: if '\t' in line: - sep='\t' + sep = '\t' if ',' in line: - decimal=',' + decimal = ',' else: - decimal='.' + decimal = '.' elif ';' in line: - sep=';' + sep = ';' if ',' in line: - decimal=',' + decimal = ',' else: - decimal='.' + decimal = '.' elif ', ' in line: - sep=',' - decimal='.' + sep = ',' + decimal = '.' else: - sep=' ' + sep = ' ' if ',' in line: - decimal=',' + decimal = ',' else: - decimal='.' - skip_rows=0 - names=None + decimal = '.' + skip_rows = 0 + names = None for line in file.keys(): - entries=str(line).split(sep) + entries = str(line).split(sep) for entry in entries: try: float(entry) - except: + except BaseException: skip_rows += 1 break if names is None: for num, line in file.iterrows(): for char in line: - entries=str(char).split(sep) + entries = str(char).split(sep) for entry in entries: try: float(entry) - except: + except BaseException: skip_rows += 1 break - names=['x', 'y', 'vx', 'vy'] + names = ['x', 'y', 'vx', 'vy'] for part in range(1, len(entries) - 3): names.append('val-{}'.format(part)) - data=pd.read_csv(fname, + data = pd.read_csv(fname, decimal=decimal, skiprows=skip_rows - 1 if skip_rows != 0 else 0, sep=sep, header=0 if skip_rows != 0 else None, names=names) else: - data='File could not be read. Possibly it is an image file.' + data = 'File could not be read. Possibly it is an image file.' return data def __init_listbox(self, key): @@ -757,58 +758,58 @@ def __init_listbox(self, key): Key of a settings object. """ # root widget - f=ttk.Frame(self) + f = ttk.Frame(self) f.pack(side='bottom', fill='both', expand='True') # filter hint - hint_frame=ttk.Frame(f) - hint_title=ttk.Label(hint_frame, text=' filter: ') - self.filter_hint=ttk.Label(hint_frame, + hint_frame = ttk.Frame(f) + hint_title = ttk.Label(hint_frame, text=' filter: ') + self.filter_hint = ttk.Label(hint_frame, text='None') hint_title.pack(anchor='nw', side='left') self.filter_hint.pack(anchor='nw') hint_frame.pack(side='top', fill='x', expand='False') # number of files - num_frame=ttk.Frame(f) - num_label=ttk.Label(num_frame, text=' number of files: ') - self.num_label=ttk.Label(num_frame, + num_frame = ttk.Frame(f) + num_label = ttk.Label(num_frame, text=' number of files: ') + self.num_label = ttk.Label(num_frame, text=len(self.p['fnames'])) num_label.pack(anchor='nw', side='left') self.num_label.pack(anchor='nw') num_frame.pack(side='top', fill='x', expand='False') # scrolling - sbx=ttk.Scrollbar(f, orient="horizontal") + sbx = ttk.Scrollbar(f, orient="horizontal") sbx.pack(side='top', fill='x') - sby=ttk.Scrollbar(f, orient="vertical") + sby = ttk.Scrollbar(f, orient="vertical") sby.pack(side='right', fill='y') - self.lb=tk.Listbox(f, yscrollcommand=sbx.set) - self.lb=tk.Listbox(f, yscrollcommand=sby.set) + self.lb = tk.Listbox(f, yscrollcommand=sbx.set) + self.lb = tk.Listbox(f, yscrollcommand=sby.set) sbx.config(command=self.lb.xview) sby.config(command=self.lb.yview) - self.lb['width']=25 + self.lb['width'] = 25 # background variable self.tkvars.update({key: tk.StringVar()}) self.tkvars[key].set(self.p['fnames']) - self.lb['listvariable']=self.tkvars[key] + self.lb['listvariable'] = self.tkvars[key] # interaction self.lb.bind('<>', self.__listbox_selection_changed) self.lb.pack(side='top', fill='y', expand='True') # navigation buttons - f=ttk.Frame(f) + f = ttk.Frame(f) ttk.Button(f, text='< back', command=lambda: self.navigate('back')).pack( - side='left', fill='x') + side='left', fill='x') ttk.Button(f, text='forward >', command=lambda: self.navigate('forward')).pack( - side='right', fill='x') + side='right', fill='x') f.pack() def get_filelistbox(self): @@ -835,22 +836,22 @@ def navigate(self, direction): direction : str 'back' or 'forward'. """ - pattern_lst=str2list(self.p['navi_pattern']) - dirname=os.path.dirname(self.p['fnames'][0]) - files=os.listdir(dirname) + pattern_lst = str2list(self.p['navi_pattern']) + dirname = os.path.dirname(self.p['fnames'][0]) + files = os.listdir(dirname) if direction == 'back': self.p.navi_position -= 1 if self.p.navi_position == -1: - self.p.navi_position=len(pattern_lst) - 1 + self.p.navi_position = len(pattern_lst) - 1 elif direction == 'forward': self.p.navi_position += 1 if self.p.navi_position == len(pattern_lst): - self.p.navi_position=0 - filtered=(self.file_filter( - files, - pattern_lst[self.p.navi_position])) + self.p.navi_position = 0 + filtered = (self.file_filter( + files, + pattern_lst[self.p.navi_position])) if filtered: - filtered=sorted([dirname + os.sep + f for f in filtered]) + filtered = sorted([dirname + os.sep + f for f in filtered]) self.tkvars['fnames'].set(filtered) self.get_settings() @@ -877,10 +878,10 @@ def file_filter(self, files, pattern): str[] List items that match the pattern. """ - filtered=[] + filtered = [] self.filter_hint.config(text=pattern) print('file filter: ' + pattern) - p=re.compile(pattern) + p = re.compile(pattern) for f in files: if p.search(f): filtered.append(f) @@ -894,15 +895,15 @@ def __init_text_area(self, key): when the mouse leaves the text area. """ self.ta.update({key: (tk.Text(self.set_frame[-1], undo=True))}) - ta=self.ta[list(self.ta)[-1]] + ta = self.ta[list(self.ta)[-1]] ta.pack() ta.bind('', (lambda _: self.__get_text(key, ta))) ttk.Button(self.set_frame[-1], text='clear', command=lambda: ta.delete( - '1.0', tk.END) - ).pack(fill='x') + '1.0', tk.END) + ).pack(fill='x') ttk.Button(self.set_frame[-1], text='undo', command=lambda: ta.edit_undo() @@ -914,12 +915,12 @@ def __init_text_area(self, key): def __get_text(self, key, text_area): """Get text from text_area and copy it to parameter object.""" - self.p[key]=text_area.get('1.0', tk.END) + self.p[key] = text_area.get('1.0', tk.END) def __listbox_selection_changed(self, event): """Handles selection change events of the file listbox.""" try: - self.index=event.widget.curselection()[0] + self.index = event.widget.curselection()[0] except IndexError: pass # nothing selected else: @@ -930,9 +931,9 @@ def __listbox_selection_changed(self, event): def __init_labelframe(self, key): """Add a label frame for widgets.""" - f=ttk.Frame(self.set_frame[-1]) - self.pane=ttk.Panedwindow(f, orient='vertical', width=400) - self.lf=tk.LabelFrame(self.pane, text=self.p.label[key]) + f = ttk.Frame(self.set_frame[-1]) + self.pane = ttk.Panedwindow(f, orient='vertical', width=400) + self.lf = tk.LabelFrame(self.pane, text=self.p.label[key]) self.lf.config(borderwidth=2, width=400, relief='groove') self.pane.add(self.lf) self.pane.pack(side='left', fill='both') @@ -940,12 +941,12 @@ def __init_labelframe(self, key): def __init_sub_labelframe(self, key): """Add a label frame for widgets.""" - self.sub_lf=tk.LabelFrame(self.lf, text=self.p.label[key]) + self.sub_lf = tk.LabelFrame(self.lf, text=self.p.label[key]) self.sub_lf.config(borderwidth=2, width=400, relief='groove') self.sub_lf.pack(fill='both', pady=4, padx=4) def __init_post_button(self, event): - f=ttk.Frame(self.lf) + f = ttk.Frame(self.lf) f.pack(fill='both') ttk.Button(f, text='start postprocessing', @@ -953,21 +954,21 @@ def __init_post_button(self, event): def __init_horizontal_spacer(self, key): """Add a horizontal spacer line for widgets.""" - f=ttk.Frame(self.lf) - hs=ttk.Separator(f) + f = ttk.Frame(self.lf) + hs = ttk.Separator(f) hs.pack(fill='x') f.pack(fill='both') def __init_sub_horizontal_spacer(self, key): """Add a horizontal spacer line for widgets""" - f=ttk.Frame(self.sub_lf) - hs=ttk.Separator(f) + f = ttk.Frame(self.sub_lf) + hs = ttk.Separator(f) hs.pack(fill='x') f.pack(fill='both') def __init_label(self, key): - f=ttk.Frame(self.lf) - label1=ttk.Label(f, + f = ttk.Frame(self.lf) + label1 = ttk.Label(f, text=self.p.label[key]) label1.pack(side='left') f.pack() @@ -986,14 +987,14 @@ def __init_entry(self, key): key : str Key of a parameter obj. """ - padding=2 + padding = 2 # sub label frames if (self.p.type[key] == 'sub_int' or self.p.type[key] == 'sub_float' or self.p.type[key] == 'sub'): - f=ttk.Frame(self.sub_lf) + f = ttk.Frame(self.sub_lf) f.pack(fill='x') - l=ttk.Label(f, text=self.p.label[key]) + l = ttk.Label(f, text=self.p.label[key]) CreateToolTip(l, self.p.help[key]) l.pack(side='left', padx=padding, pady=padding) if self.p.type[key] == 'sub_int': @@ -1003,19 +1004,19 @@ def __init_entry(self, key): elif self.p.type[key] == 'sub': self.tkvars.update({key: tk.StringVar()}) if self.p.hint[key] is not None: - e=ttk.OptionMenu(f, + e = ttk.OptionMenu(f, self.tkvars[key], 'spacer', *self.p.hint[key]) else: - e=ttk.Entry(f, width=17) - e['textvariable']=self.tkvars[key] + e = ttk.Entry(f, width=17) + e['textvariable'] = self.tkvars[key] CreateToolTip(e, self.p.help[key]) e.pack(side='right', padx=padding, pady=padding) else: - f=ttk.Frame(self.lf) + f = ttk.Frame(self.lf) f.pack(fill='x') - l=ttk.Label(f, text=self.p.label[key]) + l = ttk.Label(f, text=self.p.label[key]) CreateToolTip(l, self.p.help[key]) l.pack(side='left', padx=padding, pady=padding) if self.p.type[key] == 'int': @@ -1025,26 +1026,26 @@ def __init_entry(self, key): else: self.tkvars.update({key: tk.StringVar()}) if self.p.hint[key] is not None: - e=ttk.OptionMenu(f, + e = ttk.OptionMenu(f, self.tkvars[key], 'spacer', *self.p.hint[key]) else: - e=ttk.Entry(f, width=17) - e['textvariable']=self.tkvars[key] + e = ttk.Entry(f, width=17) + e['textvariable'] = self.tkvars[key] CreateToolTip(e, self.p.help[key]) e.pack(side='right', padx=padding, pady=padding) def __init_checkbutton(self, key): """Create a checkbutton with label and tooltip.""" - f=ttk.Frame(self.lf) + f = ttk.Frame(self.lf) f.pack(fill='x') self.tkvars.update({key: tk.BooleanVar()}) self.tkvars[key].set(bool(self.p[key])) - cb=ttk.Checkbutton(f) - cb['variable']=self.tkvars[key] - cb['onvalue']=True - cb['offvalue']=False - cb['text']=self.p.label[key] + cb = ttk.Checkbutton(f) + cb['variable'] = self.tkvars[key] + cb['onvalue'] = True + cb['offvalue'] = False + cb['text'] = self.p.label[key] CreateToolTip(cb, self.p.help[key]) cb.pack(side='left') @@ -1052,25 +1053,25 @@ def __init_sub_checkbutton(self, key): """ Create a checkbutton with label and tooltip. """ - f=ttk.Frame(self.sub_lf) + f = ttk.Frame(self.sub_lf) f.pack(fill='x') self.tkvars.update({key: tk.BooleanVar()}) self.tkvars[key].set(bool(self.p[key])) - cb=ttk.Checkbutton(f) - cb['variable']=self.tkvars[key] - cb['onvalue']=True - cb['offvalue']=False - cb['text']=self.p.label[key] + cb = ttk.Checkbutton(f) + cb['variable'] = self.tkvars[key] + cb['onvalue'] = True + cb['offvalue'] = False + cb['text'] = self.p.label[key] CreateToolTip(cb, self.p.help[key]) cb.pack(side='left') def __init_vec_colorpicker(self, key): - whitespace=' ' - f=ttk.Frame(self.lf) - l=ttk.Label(f, text='invalid vector color') + whitespace = ' ' + f = ttk.Frame(self.lf) + l = ttk.Label(f, text='invalid vector color') CreateToolTip(l, self.p.help[key]) l.pack(side='left') - self.invalid_color=tk.Button(f, + self.invalid_color = tk.Button(f, text=whitespace, bg=self.p['invalid_color'], relief='groove', @@ -1078,12 +1079,12 @@ def __init_vec_colorpicker(self, key): self.invalid_color.pack(side='right') f.pack(fill='x') - f=ttk.Frame(self.lf) - l=ttk.Label(f, text='valid vector color') + f = ttk.Frame(self.lf) + l = ttk.Label(f, text='valid vector color') CreateToolTip(l, self.p.help[key]) l.pack(side='left') print(self.p['valid_color']) - self.valid_color=tk.Button(f, + self.valid_color = tk.Button(f, text=whitespace, bg=self.p['valid_color'], relief='groove', @@ -1092,15 +1093,15 @@ def __init_vec_colorpicker(self, key): f.pack(fill='x') def invalid_colorpicker(self): - color=colorchooser.askcolor()[1] + color = colorchooser.askcolor()[1] if color is not None: - self.p['invalid_color']=color + self.p['invalid_color'] = color self.invalid_color.config(bg=self.p['invalid_color']) def valid_colorpicker(self): - color=colorchooser.askcolor()[1] + color = colorchooser.askcolor()[1] if color is not None: - self.p['valid_color']=color + self.p['valid_color'] = color self.valid_color.config(bg=self.p['valid_color']) def log(self, columninformation=None, timestamp=False, text=None, @@ -1135,19 +1136,19 @@ def log(self, columninformation=None, timestamp=False, text=None, if text is not None: self.ta["lab_book_content"].insert(tk.END, text + '\n') if timestamp: - td=datetime.today() - s='-'.join((str(td.year), str(td.month), str(td.day))) + \ + td = datetime.today() + s = '-'.join((str(td.year), str(td.month), str(td.day))) + \ ' ' + \ ':'.join((str(td.hour), str(td.minute), str(td.second))) self.log(text=s) if group is not None: self.log(text='Parameters:') for key in self.p.param: - key_type=self.p.type[key] + key_type = self.p.type[key] if key_type not in ['labelframe', 'sub_labelframe', 'h-spacer', 'sub_h-spacer', 'post_button']: if group < self.p.index[key] < group + 1000: - s=key + ': ' + str(self.p[key]) + s = key + ': ' + str(self.p[key]) self.log(text=s) if columninformation is not None: self.ta["lab_book_content"] \ @@ -1162,7 +1163,7 @@ def show_information(self, fname): fname : str A filename. """ - data=self.load_pandas(fname) + data = self.load_pandas(fname) if isinstance(data, str): self.log(text=data) else: @@ -1172,11 +1173,11 @@ def get_settings(self): """Copy widget variables to the parameter object.""" for key in self.tkvars: if self.p.type[key] == 'str[]': - self.p[key]=str2list(self.tkvars[key].get()) + self.p[key] = str2list(self.tkvars[key].get()) elif self.p.type[key] == '[]': - self.p[key]=self.p[key] + self.p[key] = self.p[key] else: - self.p[key]=self.tkvars[key].get() + self.p[key] = self.tkvars[key].get() for key in self.ta: self.__get_text(key, self.ta[key]) @@ -1191,9 +1192,9 @@ def set_settings(self): def select_image_files(self): """Show a file dialog to select one or more filenames.""" print('Use Ctrl + Shift to select multiple files.') - files=filedialog.askopenfilenames(multiple=True) + files = filedialog.askopenfilenames(multiple=True) if len(files) > 0: - self.p['fnames']=list(files) + self.p['fnames'] = list(files) self.tkvars['fnames'].set(self.p['fnames']) # update file count @@ -1201,10 +1202,10 @@ def select_image_files(self): def open_directory(self): """Show a dialog for opening a directory.""" - dir=filedialog.askdirectory() + dir = filedialog.askdirectory() if len(dir) > 0: - files=[dir + os.sep + file for file in os.listdir(dir)] - self.p['fnames']=list(files) + files = [dir + os.sep + file for file in os.listdir(dir)] + self.p['fnames'] = list(files) self.tkvars['fnames'].set(self.p['fnames']) self.navigate('back') @@ -1223,20 +1224,20 @@ def show(self, fname): fname : str A filename. """ - ext=fname.split('.')[-1] + ext = fname.split('.')[-1] self.fig.clear() - data=self.load_pandas(fname) + data = self.load_pandas(fname) if ext in ['txt', 'dat', 'jvc', 'vec', 'csv']: if self.p['plot_type'] == 'vectors': vec_plot.vector( - data, - self.p, - self.fig, - invert_yaxis=self.p['invert_yaxis'], - scale=self.p['vec_scale'], - width=self.p['vec_width'], - valid_color=self.p['valid_color'], - invalid_color=self.p['invalid_color'] + data, + self.p, + self.fig, + invert_yaxis=self.p['invert_yaxis'], + scale=self.p['vec_scale'], + width=self.p['vec_width'], + valid_color=self.p['valid_color'], + invalid_color=self.p['invalid_color'] ) elif self.p['plot_type'] == 'profiles': vec_plot.profiles(data, self.p, @@ -1274,7 +1275,7 @@ def show_img(self, fname): fname : str Pathname of an image file. """ - img=piv_tls.imread(fname) + img = piv_tls.imread(fname) print('\nimage data type: {}'.format(img.dtype)) print('max count: {}'.format(img.max())) print('min count {}:'.format(img.min())) @@ -1284,28 +1285,28 @@ def show_img(self, fname): 'This may cause a loss of precision.') print('Processing image.') - img=img.astype(np.int32) + img = img.astype(np.int32) # generate background if needed if self.p['background_subtract'] and \ self.p['background_type'] != 'minA - minB': - background=gen_background(self.p) + background = gen_background(self.p) elif self.p['background_subtract'] and \ self.p['background_type'] == 'minA - minB': if fname == self.p['fnames'][-1]: - img2=self.p['fnames'][-2] - img2=piv_tls.imread(img2) - background=gen_background(self.p, img2, img) + img2 = self.p['fnames'][-2] + img2 = piv_tls.imread(img2) + background = gen_background(self.p, img2, img) else: - img2=self.p['fnames'][self.index + 1] - img2=piv_tls.imread(img2) - background=gen_background(self.p, img, img2) + img2 = self.p['fnames'][self.index + 1] + img2 = piv_tls.imread(img2) + background = gen_background(self.p, img, img2) else: - background=None + background = None # preprocessing method became parameter due to the AddInHandler - img=process_images(self, img, self.preprocessing_methods, + img = process_images(self, img, self.preprocessing_methods, background=background) - img=img.astype(np.int32) + img = img.astype(np.int32) print('Processed image.') print('max count: {}'.format(img.max())) @@ -1327,7 +1328,7 @@ def destroy_for_new_addins(self) -> None: """ print('Updating GUI') # reset the plot_type because the chosen one might not longer exist - self.p["plot_type"]='contour + vectors' + self.p["plot_type"] = 'contour + vectors' # save old gui status self.p.dump_settings(self.p.params_fname) # destroy old gui @@ -1356,7 +1357,7 @@ def destroy(self): if __name__ == '__main__': - openPivGui=OpenPivGui() + openPivGui = OpenPivGui() # a good starting size for the GUI openPivGui.geometry("1150x690") openPivGui.mainloop() diff --git a/openpivgui/PostProcessing.py b/openpivgui/PostProcessing.py index a4e0bdb7..b78005b8 100644 --- a/openpivgui/PostProcessing.py +++ b/openpivgui/PostProcessing.py @@ -85,17 +85,17 @@ def global_std(self): result_fnames = [] for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) - + mask = piv_vld.global_std( data[:, 2], data[:, 3], std_threshold=self.p['global_std_threshold']) - + save_fname = create_save_vec_fname( path=f, postfix='_std_thrhld') save(data[:, 0], data[:, 1], - data[:, 2], + data[:, 2], data[:, 3], data[:, 4] + mask, data[:, 5], @@ -118,11 +118,11 @@ def global_val(self): data[:, 2], data[:, 3], u_thresholds=(self.p['MinU'], self.p['MaxU']), v_thresholds=(self.p['MinV'], self.p['MaxV'])) - + save_fname = create_save_vec_fname( path=f, postfix='_glob_thrhld') - + save(data[:, 0], data[:, 1], data[:, 2], @@ -145,23 +145,23 @@ def local_median(self): result_fnames = [] for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) - - u = data[:, 2].reshape(len(set(data[:,0])), len(set(data[:,1]))) - v = data[:, 3].reshape(len(set(data[:,0])), len(set(data[:,1]))) + + u = data[:, 2].reshape(len(set(data[:, 0])), len(set(data[:, 1]))) + v = data[:, 3].reshape(len(set(data[:, 0])), len(set(data[:, 1]))) mask = piv_vld.local_median_val( u, v, u_threshold=self.p['local_median_threshold'], v_threshold=self.p['local_median_threshold'], size=self.p['local_median_size']) - + save_fname = create_save_vec_fname( path=f, postfix='_med_thrhld') - + save(data[:, 0], data[:, 1], - data[:, 2], + data[:, 2], data[:, 3], data[:, 4] + mask.flatten(), data[:, 5], @@ -176,11 +176,11 @@ def repl_outliers(self): for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) - shapes = (len(set(data[:,0])), len(set(data[:,1]))) + shapes = (len(set(data[:, 0])), len(set(data[:, 1]))) u = data[:, 2].reshape(shapes) v = data[:, 3].reshape(shapes) - flags = data[:, 4].reshape(shapes).astype(bool) + flags = data[:, 4].reshape(shapes).astype(bool) u, v = piv_flt.replace_outliers( u, v, @@ -193,8 +193,8 @@ def repl_outliers(self): postfix='_repl') save(data[:, 0], data[:, 1], - u.flatten(), - v.flatten(), # <- holes filled version + u.flatten(), + v.flatten(), # <- holes filled version data[:, 4], data[:, 5], save_fname, @@ -207,11 +207,11 @@ def smoothn_r(self): result_fnames = [] for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) - shapes = (len(set(data[:,0])), len(set(data[:,1]))) + shapes = (len(set(data[:, 0])), len(set(data[:, 1]))) u = data[:, 2].reshape(shapes) v = data[:, 3].reshape(shapes) - + u, _, _, _ = piv_smt.smoothn( data[:, 2], s=self.p['smoothn_val'], isrobust=self.p['robust']) v, _, _, _ = piv_smt.smoothn( From 22fd65693f6b80e3ab91b131dfa05a1a063c0c57 Mon Sep 17 00:00:00 2001 From: Alex Liberzon Date: Fri, 19 Apr 2024 21:35:35 +0300 Subject: [PATCH 5/6] removed unnecessary files --- .gitmodules | 3 +++ openpiv-python | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 openpiv-python diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..77af87ad --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "openpiv-python"] + path = openpiv-python + url = https://github.com/openpiv/openpiv-python diff --git a/openpiv-python b/openpiv-python new file mode 160000 index 00000000..55b811c5 --- /dev/null +++ b/openpiv-python @@ -0,0 +1 @@ +Subproject commit 55b811c55134a2a1d199956f35786db19ba8ff5a From c7d72b33deb3fd9304eb5dba59a4195a0a26e690 Mon Sep 17 00:00:00 2001 From: Alex Liberzon Date: Fri, 19 Apr 2024 21:36:05 +0300 Subject: [PATCH 6/6] removed obsolete --- openpivgui.egg-info/PKG-INFO | 86 ------------------------ openpivgui.egg-info/SOURCES.txt | 26 ------- openpivgui.egg-info/dependency_links.txt | 1 - openpivgui.egg-info/requires.txt | 2 - openpivgui.egg-info/top_level.txt | 1 - 5 files changed, 116 deletions(-) delete mode 100644 openpivgui.egg-info/PKG-INFO delete mode 100644 openpivgui.egg-info/SOURCES.txt delete mode 100644 openpivgui.egg-info/dependency_links.txt delete mode 100644 openpivgui.egg-info/requires.txt delete mode 100644 openpivgui.egg-info/top_level.txt diff --git a/openpivgui.egg-info/PKG-INFO b/openpivgui.egg-info/PKG-INFO deleted file mode 100644 index 0017fdd3..00000000 --- a/openpivgui.egg-info/PKG-INFO +++ /dev/null @@ -1,86 +0,0 @@ -Metadata-Version: 2.1 -Name: openpivgui -Version: 0.4.13 -Summary: A simple GUI for Open PIV. -Home-page: https://github.com/OpenPIV/openpiv_tk_gui -Author: P. Vennemann and contributors. -Author-email: vennemann@fh-muenster.de -License: UNKNOWN -Description: ![Upload Python Package](https://github.com/OpenPIV/openpiv_tk_gui/workflows/Upload%20Python%20Package/badge.svg) - - # A GUI for Open PIV - - This graphical user interface provides an efficient workflow for evaluating and postprocessing particle image velocimetry (PIV) images. OpenPivGui relies on the Python libraries provided by the [OpenPIV project](http://www.openpiv.net/). - - ![Screen shot of the GUI showing a vector plot.](https://raw.githubusercontent.com/OpenPIV/openpiv_tk_gui/master/fig/open_piv_gui_vector_plot.png) - - [Installation](#installation) - - [Launching](#launching) - - [Usage](#usage) - - [Video Tutorial](#video_tuturial) - - [Documentation](#documentation) - - [Contribution](#contribution) - - - ## Installation - - You may use Pip to install `OpenPivGui`: - - ``` - pip3 install openpivgui - ``` - - Alternatively, Conda may also work: - - ``` - conda install -c conda-forge openpivgui - ``` - - ## Launching - - Launch `OpenPivGui` by executing: - - ``` - python3 -m openpivgui.OpenPivGui - ``` - - ## Usage - - 1. Press the button »open directory«. Choose a directory that contains PIV images. Use the »back« or »forward« button to filter the directory content, until there is a list of images in the file list on the right side of the OpenPivGui. - 2. To inspect the images, click on the links in the file-list. - 3. Walk through the riders, select the desired functions, and edit the corresponding parameters. - 4. Press »start processing« to start the evaluation. - 5. Inspect the results by clicking on the links in the file-list. - 6. Use the »back« and »forward« buttons to inspect intermediate results. - 7. Use »dump settings« to document your project. You can recall the settings anytime by pressing »load settings«. - - - ## Video tutorial - - Learn how to use and extend OpenPivGui [watching a less than eight minute video tutorial](https://video.fh-muenster.de/Panopto/Pages/Viewer.aspx?id=309dccc2-af58-44e0-8cd3-ab9500c5b7f4). - - - ## Documentation - - Find the [detailed documentation on readthedocs.io](https://openpiv-tk-gui.readthedocs.io/en/latest/index.html). - - - ## Contribution - - Contributions are very welcome! Please follow the [step by step guide in the documentation](https://openpiv-tk-gui.readthedocs.io/en/latest/contribution.html). - - ## Related - - Also check out [JPIV](https://eguvep.github.io/jpiv/index.html). - -Platform: UNKNOWN -Classifier: Programming Language :: Python :: 3 -Classifier: License :: OSI Approved :: GNU General Public License (GPL) -Classifier: Operating System :: OS Independent -Requires-Python: >=3.0 -Description-Content-Type: text/markdown diff --git a/openpivgui.egg-info/SOURCES.txt b/openpivgui.egg-info/SOURCES.txt deleted file mode 100644 index 3ea3556e..00000000 --- a/openpivgui.egg-info/SOURCES.txt +++ /dev/null @@ -1,26 +0,0 @@ -MANIFEST.in -README.md -setup.py -./openpivgui/res/icon.png -openpivgui/AddInHandler.py -openpivgui/CreateToolTip.py -openpivgui/ErrorChecker.py -openpivgui/MultiProcessing.py -openpivgui/OpenPivGui.py -openpivgui/OpenPivParams.py -openpivgui/PostProcessing.py -openpivgui/PreProcessing.py -openpivgui/__init__.py -openpivgui/open_piv_gui_tools.py -openpivgui/vec_plot.py -openpivgui.egg-info/PKG-INFO -openpivgui.egg-info/SOURCES.txt -openpivgui.egg-info/dependency_links.txt -openpivgui.egg-info/requires.txt -openpivgui.egg-info/top_level.txt -openpivgui/AddIns/AddIn.py -openpivgui/AddIns/__init__.py -openpivgui/AddIns/advanced_filtering_addin_preprocessing.py -openpivgui/AddIns/repl_outliers_addin_postprocessing.py -openpivgui/AddIns/sig2noise_addin_postprocessing.py -openpivgui/AddIns/user_function_addin_other.py \ No newline at end of file diff --git a/openpivgui.egg-info/dependency_links.txt b/openpivgui.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891..00000000 --- a/openpivgui.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/openpivgui.egg-info/requires.txt b/openpivgui.egg-info/requires.txt deleted file mode 100644 index 4390b482..00000000 --- a/openpivgui.egg-info/requires.txt +++ /dev/null @@ -1,2 +0,0 @@ -OpenPiv==0.23.8 -pandas diff --git a/openpivgui.egg-info/top_level.txt b/openpivgui.egg-info/top_level.txt deleted file mode 100644 index 2fd2a22e..00000000 --- a/openpivgui.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -openpivgui