From: illysam Date: Tue, 2 Mar 2010 20:46:08 +0000 (+0000) Subject: Hooke(GUI) X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=a50de4c8f7a86fed3daf7f0fba9fba6bbbb8fd8d;p=hooke.git Hooke(GUI) hooke.py - added version information for ConfigObj and wxPropGrid in do_version - added preferences for playlist an workdir - UpdatePlot now only uses data and not results to set the scale decimals and prefixes ReadMe.txt - updated the Wiki page HookeGUI and used it as the ReadMe hooke configspec.ini/hooke.ini - removed section 'core' drivers/mfp1d.py - deflection and LVDT files can now be stored in the same folder (forgot about the filemask in do_genlist) drivers/mfp3d.py - improved file recognition lib/curve.py - renamed Multiplier/multiplier to Prefix/prefix lib/libhooke.py - moved pickup_contact_point to autopeak.py lib/results.py - removed old code plugins/autopeak.py - added pickup_contact_point (was in libhooke before) plugins/core.ini - added 'preferences'options: playlist and workdir - renamed 'preferences'options: multiplier to prefix plugins/generalvclamp.py - renamed multiplier to prefix plugins/playlist.ini and playlist.py - added option: detect_mfp1d plugins/plot.ini and plot.py - renames option 'plot' to 'preferences' - renamed multiplier to prefix plugins/procplots.ini and procplots.py - renamed multiplier to prefix --- diff --git a/ReadMe.txt b/ReadMe.txt index 14b05e8..ffa9f78 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -1,31 +1,30 @@ -Hooke(GUI) -Hooke(GUI) is a GUI-only version of Hooke. The fact that all commands can be chosen from the GUI and do not need to be typed into the command line, provides a different user experience. This might be beneficial for some users. - -The GUI code is based on the examples from the wxPython DEMO, copyright 1997-2006 by Robin DUnn and Total Control Software. +#summary Introduction to Hooke(GUI). -The property editor is based on the code in test_propgrid.py provided with the wxPropertyGrid download copyright 2006-2009 by Jaakko Salli. += Hooke(GUI) = +Hooke(GUI) is a GUI-only version of Hooke. The fact that all commands can be chosen from the GUI and do not need to be typed into the command line, provides a different user experience. This might be beneficial for some users. == Installation == -Please follow the installation guidelines for Hooke. You don't need to install wxMPL to run Hooke(GUI). However, you need to install ConfigObj (http://www.voidspace.org.uk/python/configobj.html) and wxPropertyGrid (http://wxpropgrid.sourceforge.net/cgi-bin/index). Follow the installation instructions on the respective websites. +Please follow the installation guidelines [HowToInstall here]. You don't need to install wxMPL to run Hooke(GUI). However, you need to install [http://www.voidspace.org.uk/python/configobj.html ConfigObj] and [http://wxpropgrid.sourceforge.net/cgi-bin/index wxPropertyGrid]. Follow the installation instructions on the respective websites. Unfortunately, there seem to be some issues with wxPropertyGrid on Linux, Mac OS X and other nix systems. Hooke(GUI) has been developed and tested with this combination of libraries on Windows (XP, Vista, 7): - * Python: 2.6.4 - * wxPython: 2.8.10.1 - * wxPropertyGrid: 1.4.9.1 - * matplotlib: 0.99.1 - * SciPy: 0.7.1 - * NumPy: 1.3.0 + * [http://www.python.org Python]: 2.6.4 + * [http://www.wxpython.org wxPython]: 2.8.10.1 + * [http://wxpropgrid.sourceforge.net/cgi-bin/index wxPropertyGrid]: 1.4.10 + * [http://matplotlib.sourceforge.net/ matplotlib]: 0.99.1 + * [http://www.scipy.org/ SciPy]: 0.7.1 + * [http://www.numpy.org/ NumPy]: 1.4.0 + * [http://www.voidspace.org.uk/python/configobj.html ConfigObj]: 4.6.0 -The program will probably work fine with other combinations as well. If you can make it work, please post your combination on the Hooke website indicating that you are using Hooke(GUI). +The program will probably work fine with other combinations as well. If you can make it work, please post your combination [ListKnownWorkingLibraries here] indicating that you are using Hooke(GUI). -This version is not yet complete but provides the basic functionality required to do simple force curve filtering and autopeak analysis. +This version is not yet complete but provides the basic functionality required to do simple force curve filtering and autopeak analysis. Please create a new [Issues issue] if you urgently need a feature that is not implemented. == Interface == -Starting Hooke(GUI) for the first time, you will see the central plot area with the current plot surrounded by the following windows (the F key toggles the visibility of the window): +Starting Hooke(GUI) for the first time, you will see the central plot area with the current plot surrounded by the following windows (the F key toggles the visibility of the panel): # Folders (F5) # Playlists (F6) @@ -34,42 +33,61 @@ Starting Hooke(GUI) for the first time, you will see the central plot area with # Assistant (F9) # Results (F10) # Output (F11) + # Note (F12) +http://nanoscience-dev.concordia.ca/custom/images/hooke/hooke%20gui%20screenshot.jpg Initially, the window will be rather small in order to work with small screen resolutions. Adjust the size and position to your liking. Above the windows you see the navigation toolbar to switch from one curve to another (next/previous). +=== Plot area === +The plot area can be customised by setting 'preferences' in the core plug-in. + * hide_curve_extension: hides the curve extension in the title of the plot (and from the playlist in the playlists panel) + * legend: show or hide the legend + * use_zero: display '0' instead of _e.g._ '0.00' on the axes + * decimals (x_decimals, y_decimals): set the decimal places for the x and y axes + * prefixes(x_prefix, y_prefix): set the prefix for the x and y axes + +These are global settings. Individual plots can be customised with the same options (except hide_curve_extension) by setting 'preferences' in the plot plug-in. + === 1. Folders === -Here you can navigate your file system and double click on a saved playlist to open it. In order to change the starting folder, you have to edit _hooke.ini_ in the _config_ folder (core/workdir). In the near future, core settings will be made editable from the GUI. +Here you can navigate your file system and double click on a saved playlist to open it. You can change the initial folder by modifying 'workdir' in the 'preferences' (core plug-in). === 2. Playlists === You can manage several playlists in this window. As the GUI is rather flexible, it is possible to display the curves from different playlists side by side to compare them (relatively handy when comparing different fit parameters). You can double-click a file in the playlist to display it in the plot area. Deleting entire playlists or single files can be accomplished by right-clicking and selecting 'Delete'. === 3. Commands (or Settings and commands) === -All available commands (_i.e._ do_COMMAND) are listed under their corresponding plug-in. In order to see a plug-in and its commands, you have to edit _hooke.ini_ in the _config_ folder (plugins/PLUGINNAME = True). Selecting a plug-in or command will display the associated help in the Assistant window (see below). You can edit the properties of the selected command in the Properties window (see below) and click 'Execute' to run the selected command. If you do not need to modify any properties, you can double-click a command to run it. +All available commands (_i.e._ do_COMMAND) are listed under their corresponding plug-in. In order to see a plug-in and its commands, you have to edit _hooke.ini_ in the _config_ folder (plugins/PLUGINNAME = True). Selecting a plug-in or command will display the associated help in the Assistant window (see below). You can edit the properties of the selected command in the Properties window (see below) and click 'Execute' to run the selected command. If you do not need to modify any properties, you can also double-click a command to run it. === 4. Properties === The properties for the command selected in the Commands window (see above) are displayed here. Edit the properties to your satisfaction (some need to be confirmed by hitting enter, this seems to be a problem in wxPropertyGrid) and click the 'Execute' button to run the selected command. Floating point values are limited to a certain number of decimals (limitation of wxPropertyGrid?) so be careful when using floating point values. === 5. Assistant === -Selecting a plug-in or command in the Commands window will display the associated help here. The help for the plug-in should give a general description of the plug-in. The help for a command should describe the properties available for this command and suggest reasonable -default values if possible. feel free to point out missing help content. +Selecting a plug-in or command in the Commands window will display the associated help here. The help for the plug-in should give a general description of the plug-in. The help for a command should describe the properties available for this command and suggest reasonable default values if possible. Feel free to point out missing help content. === 6. Results === -The results from the 'autopeak' command are displayed here. Initially, all results are checked (i.e visible). If you want to hide a fit, simply uncheck it. Hidden curves will not be exported either. You can only display one type of fit result (WLC, FJC, etc.) at a time (results plug-in - show_results). +The results from the 'autopeak' or 'multidistance' command are displayed here. Initially, all results are checked (i.e visible). If you want to hide a result, simply uncheck it. Hidden curves will not be exported either. You can only display one type of fit result (WLC, FJC, etc.) at a time and you can switch between result types (results plug-in - show_results). === 7. Output === The Output window serves as a log where pertinent information is displayed. If something does not work the way you expect it, have a look here to see if there is more information available. +=== 8. Note === +A note can be added to every curve: enter your note and click 'Update note'. With the copylog command (core plug-in) you can copy all the files with a note to a different folder. + + == General remarks == Ignore the text on the Welcome tab. This tab is more like a proof of principle and will contain a short how-to in the future (once the howto is written). Hooke(GUI) will remember the size and position of the main window. -You can arrange the windows any which way you like and save this arrangement as a perspective. Hooke(GUI) will always start with the last used perspective and you can switch from one perspective to another by selecting a perspective from the perspectives menu. After deleting a perspective, the radio indicator in the perspectives menu disappears (known bug in wxPython). This is only a visual problem and does not affect anything else. +You can arrange the panels any which way you like and save this arrangement as a perspective. + +http://nanoscience-dev.concordia.ca/custom/images/hooke/hooke%20gui%20screenshot%20perspective.jpg -In order to pan the plot, zoom in and out and export the plot of your force curves, use the plot toolbar under the plot. A more detailed description is available on the matplotlib website (http://matplotlib.sourceforge.net/users/navigation_toolbar.html). +Hooke(GUI) will always start with the last used perspective and you can switch from one perspective to another by selecting a perspective from the perspectives menu. After deleting a perspective, the radio indicator in the perspectives menu disappears (known bug in wxPython). This is only a visual problem and does not affect anything else. + +In order to pan the plot, zoom in and out and export the plot of your force curves, use the plot toolbar under the plot. A more detailed description is available on the [http://matplotlib.sourceforge.net/users/navigation_toolbar.html matplotlib website]. == Some plug-ins and commands == * replot (plot): replots the current force curve from scratch eliminating any secondary plots @@ -81,13 +99,11 @@ In order to pan the plot, zoom in and out and export the plot of your force curv * overlay (export): exports all retraction curves in a playlist on the same scale. This is achieved by determining the maximum x window and adding x(max) and x(min) to all curves that are shorter than the maximum x window. Make sure to filter your playlist before running this command! == Basic analysis and autopeak == -Please follow the steps for basic analysis described on the Hooke website. Instead of typing in the command at the command-line, select it in the Commands window, set your properties in the Properties window and click on 'Execute'. - -The Brief_Autopeak_HowTo tutorial on the Hooke website is also applicable. In Hooke(GUI) you need to setup the type of fit you want to use: in the Properties of the autopeak command (autopeak plug-in) select wlc, fjc or fjcPEG from the dropdown list for the fit_function. +Please follow the steps for basic analysis described [BasicAnalysis here]. Instead of typing in the command at the command-line, select it in the Commands window, set your properties in the Properties window and click on 'Execute'. -In order to display the fitted curves on the plot, select the same type of fit in the Properties of the show_results command (results plug-in). +The [Brief_Autopeak_HowTo autopeak] tutorial is also applicable. In Hooke(GUI) you need to setup the type of fit you want to use: in the Properties of the autopeak command (autopeak plug-in) select wlc, fjc or fjcPEG from the dropdown list for the fit_function. -Be advised that notes are not yet available in Hooke(GUI). +If you run different fits (_e.g._ WLC and FJC) you can switch the display of the results with the show_results command (results plug-in). == Brief Plug-in/Properties tutorial == Have a look at the files in the _plugins_ folder. The python files contain the plotmanipulators (_i.e._ plotmanip_NAME), commands (_i.e._ do_COMMAND) and auxilliary methods. The ini files contain the information for the Properties window. You can already use a fair number of datatypes (_e.g._ integer, float, boolean, list, color, etc.) and more can be added. Be careful when using floats as there is a limit to the number of decimals (see above). The plotmanipulators and commands should read the properties directly from the ini file instead of having them passed to them as arguments. For the time being, accessor methods are located in hooke.py (_e.g._ GetBoolFromConfig()). diff --git a/config/hooke configspec.ini b/config/hooke configspec.ini index 1f02453..c5691de 100644 --- a/config/hooke configspec.ini +++ b/config/hooke configspec.ini @@ -1,7 +1,3 @@ -[core] -list = string(default = 'test.hkp') -workdir = string(default = '') - [drivers] csvdriver = boolean(default = False) hemingclamp = boolean(default = False) diff --git a/config/hooke.ini b/config/hooke.ini index f7cb6e1..fe6a3f1 100644 --- a/config/hooke.ini +++ b/config/hooke.ini @@ -4,12 +4,6 @@ command = autopeak plugin = autopeak -[core] -#substitute your work directory -workdir = C:\hooke -#the default playlist to load at startup -list = playlists/test.hkp - #this section defines which drivers have to be loaded by Hooke [drivers] csvdriver = False diff --git a/drivers/mfp1d.py b/drivers/mfp1d.py index 833eaa0..7f9f2f8 100644 --- a/drivers/mfp1d.py +++ b/drivers/mfp1d.py @@ -203,8 +203,6 @@ class mfp1dDriver(lib.driver.Driver): extension.y, retraction.y = self._load_from_file(self.filename, extract_note=True) filename = self.filename.replace('deflection', 'LVDT', 1) - path, name = os.path.split(filename) - filename = os.path.join(path, 'lvdt', name) extension.x, retraction.x = self._load_from_file(filename, extract_note=False) return [[extension.x, extension.y], [retraction.x, retraction.y]] @@ -216,11 +214,14 @@ class mfp1dDriver(lib.driver.Driver): return False name, extension = os.path.splitext(self.filename) + #the following only exist in MFP1D files, not MFP-3D #PullDist, PullDistSign, FastSamplingFrequency, SlowSamplingFrequency, FastDecimationFactor #SlowDecimationFactor, IsDualPull, InitRetDist, RelaxDist, SlowTrigger, RelativeTrigger, #EndOfNote if extension == '.ibw' and 'deflection' in name: - if 'EndOfNote' in self.lines: + #check if the corresponding LVDT file exists + filename = self.filename.replace('deflection', 'LVDT', 1) + if os.path.isfile(filename) and 'EndOfNote' in self.lines: return True else: return False diff --git a/drivers/mfp3d.py b/drivers/mfp3d.py index 5988c3f..9dde68b 100644 --- a/drivers/mfp3d.py +++ b/drivers/mfp3d.py @@ -223,7 +223,11 @@ class mfp3dDriver(lib.driver.Driver): name, extension = os.path.splitext(self.filename) if extension == '.ibw': - return True + for line in self.lines: + if line.startswith('ForceNote:'): + return True + else: + return False else: return False diff --git a/hooke.py b/hooke.py index 7033ed6..43b7510 100644 --- a/hooke.py +++ b/hooke.py @@ -25,12 +25,17 @@ import wx.lib.agw.aui as aui import wx.lib.evtmgr as evtmgr import wx.propgrid as wxpg +from matplotlib.ticker import FuncFormatter + +from configobj import __version__ as configobj_version from matplotlib import __version__ as mpl_version from numpy import __version__ as numpy_version from scipy import __version__ as scipy_version from sys import version as python_version from wx import __version__ as wx_version -from matplotlib.ticker import FuncFormatter +from wx.propgrid import PROPGRID_MAJOR +from wx.propgrid import PROPGRID_MINOR +from wx.propgrid import PROPGRID_RELEASE try: from agw import cubecolourdialog as CCD @@ -56,8 +61,6 @@ import panels.propertyeditor import panels.results import plugins -import lib.igor - global __version__ global __codename__ global __releasedate__ @@ -196,49 +199,6 @@ class HookeFrame(wx.Frame): # see the end up FrameManager::Update() for the test # code. For now, just hard code a frame minimum size self.SetMinSize(wx.Size(500, 500)) - #create panels here - self.panelAssistant = self.CreatePanelAssistant() - self.panelCommands = self.CreatePanelCommands() - self.panelFolders = self.CreatePanelFolders() - self.panelPlaylists = self.CreatePanelPlaylists() - self.panelProperties = self.CreatePanelProperties() - self.panelNote = self.CreatePanelNote() - self.panelOutput = self.CreatePanelOutput() - self.panelResults = self.CreatePanelResults() - self.plotNotebook = self.CreateNotebook() - - # add panes - self._mgr.AddPane(self.panelFolders, aui.AuiPaneInfo().Name('Folders').Caption('Folders').Left().CloseButton(True).MaximizeButton(False)) - self._mgr.AddPane(self.panelPlaylists, aui.AuiPaneInfo().Name('Playlists').Caption('Playlists').Left().CloseButton(True).MaximizeButton(False)) - self._mgr.AddPane(self.panelNote, aui.AuiPaneInfo().Name('Note').Caption('Note').Left().CloseButton(True).MaximizeButton(False)) - self._mgr.AddPane(self.plotNotebook, aui.AuiPaneInfo().Name('Plots').CenterPane().PaneBorder(False)) - self._mgr.AddPane(self.panelCommands, aui.AuiPaneInfo().Name('Commands').Caption('Settings and commands').Right().CloseButton(True).MaximizeButton(False)) - self._mgr.AddPane(self.panelProperties, aui.AuiPaneInfo().Name('Properties').Caption('Properties').Right().CloseButton(True).MaximizeButton(False)) - self._mgr.AddPane(self.panelAssistant, aui.AuiPaneInfo().Name('Assistant').Caption('Assistant').Right().CloseButton(True).MaximizeButton(False)) - self._mgr.AddPane(self.panelOutput, aui.AuiPaneInfo().Name('Output').Caption('Output').Bottom().CloseButton(True).MaximizeButton(False)) - self._mgr.AddPane(self.panelResults, aui.AuiPaneInfo().Name('Results').Caption('Results').Bottom().CloseButton(True).MaximizeButton(False)) - #self._mgr.AddPane(self.textCtrlCommandLine, aui.AuiPaneInfo().Name('CommandLine').CaptionVisible(False).Fixed().Bottom().Layer(2).CloseButton(False).MaximizeButton(False)) - #self._mgr.AddPane(panelBottom, aui.AuiPaneInfo().Name("panelCommandLine").Bottom().Position(1).CloseButton(False).MaximizeButton(False)) - - # add the toolbars to the manager - #self.toolbar=self.CreateToolBar() - self.toolbarNavigation=self.CreateToolBarNavigation() - #self._mgr.AddPane(self.toolbar, aui.AuiPaneInfo().Name('toolbar').Caption('Toolbar').ToolbarPane().Top().Layer(1).Row(1).LeftDockable(False).RightDockable(False)) - self._mgr.AddPane(self.toolbarNavigation, aui.AuiPaneInfo().Name('toolbarNavigation').Caption('Navigation').ToolbarPane().Top().Layer(1).Row(1).LeftDockable(False).RightDockable(False)) - # "commit" all changes made to FrameManager - self._mgr.Update() - #create the menubar after the panes so that the default perspective - #is created with all panes open - self.CreateMenuBar() - self.statusbar = self.CreateStatusbar() - self._BindEvents() - - name = self.config['perspectives']['active'] - menu_item = self.GetPerspectiveMenuItem(name) - if menu_item is not None: - self.OnRestorePerspective(menu_item) - #TODO: config setting to remember playlists from last session - self.playlists = self.panelPlaylists.Playlists #define the list of active drivers self.drivers = [] for driver in self.config['drivers']: @@ -308,6 +268,49 @@ class HookeFrame(wx.Frame): commands = [command for command in commands if command.startswith('do_')] if commands: self.plugins['core'] = commands + #create panels here + self.panelAssistant = self.CreatePanelAssistant() + self.panelCommands = self.CreatePanelCommands() + self.panelFolders = self.CreatePanelFolders() + self.panelPlaylists = self.CreatePanelPlaylists() + self.panelProperties = self.CreatePanelProperties() + self.panelNote = self.CreatePanelNote() + self.panelOutput = self.CreatePanelOutput() + self.panelResults = self.CreatePanelResults() + self.plotNotebook = self.CreateNotebook() + + # add panes + self._mgr.AddPane(self.panelFolders, aui.AuiPaneInfo().Name('Folders').Caption('Folders').Left().CloseButton(True).MaximizeButton(False)) + self._mgr.AddPane(self.panelPlaylists, aui.AuiPaneInfo().Name('Playlists').Caption('Playlists').Left().CloseButton(True).MaximizeButton(False)) + self._mgr.AddPane(self.panelNote, aui.AuiPaneInfo().Name('Note').Caption('Note').Left().CloseButton(True).MaximizeButton(False)) + self._mgr.AddPane(self.plotNotebook, aui.AuiPaneInfo().Name('Plots').CenterPane().PaneBorder(False)) + self._mgr.AddPane(self.panelCommands, aui.AuiPaneInfo().Name('Commands').Caption('Settings and commands').Right().CloseButton(True).MaximizeButton(False)) + self._mgr.AddPane(self.panelProperties, aui.AuiPaneInfo().Name('Properties').Caption('Properties').Right().CloseButton(True).MaximizeButton(False)) + self._mgr.AddPane(self.panelAssistant, aui.AuiPaneInfo().Name('Assistant').Caption('Assistant').Right().CloseButton(True).MaximizeButton(False)) + self._mgr.AddPane(self.panelOutput, aui.AuiPaneInfo().Name('Output').Caption('Output').Bottom().CloseButton(True).MaximizeButton(False)) + self._mgr.AddPane(self.panelResults, aui.AuiPaneInfo().Name('Results').Caption('Results').Bottom().CloseButton(True).MaximizeButton(False)) + #self._mgr.AddPane(self.textCtrlCommandLine, aui.AuiPaneInfo().Name('CommandLine').CaptionVisible(False).Fixed().Bottom().Layer(2).CloseButton(False).MaximizeButton(False)) + #self._mgr.AddPane(panelBottom, aui.AuiPaneInfo().Name("panelCommandLine").Bottom().Position(1).CloseButton(False).MaximizeButton(False)) + + # add the toolbars to the manager + #self.toolbar=self.CreateToolBar() + self.toolbarNavigation=self.CreateToolBarNavigation() + #self._mgr.AddPane(self.toolbar, aui.AuiPaneInfo().Name('toolbar').Caption('Toolbar').ToolbarPane().Top().Layer(1).Row(1).LeftDockable(False).RightDockable(False)) + self._mgr.AddPane(self.toolbarNavigation, aui.AuiPaneInfo().Name('toolbarNavigation').Caption('Navigation').ToolbarPane().Top().Layer(1).Row(1).LeftDockable(False).RightDockable(False)) + # "commit" all changes made to FrameManager + self._mgr.Update() + #create the menubar after the panes so that the default perspective + #is created with all panes open + self.CreateMenuBar() + self.statusbar = self.CreateStatusbar() + self._BindEvents() + + name = self.config['perspectives']['active'] + menu_item = self.GetPerspectiveMenuItem(name) + if menu_item is not None: + self.OnRestorePerspective(menu_item) + #TODO: config setting to remember playlists from last session + self.playlists = self.panelPlaylists.Playlists #initialize the commands tree self.panelCommands.Initialize(self.plugins) for command in dir(self): @@ -315,7 +318,7 @@ class HookeFrame(wx.Frame): self.plotmanipulators.append(lib.plotmanipulator.Plotmanipulator(method=getattr(self, command), command=command)) #load default list, if possible - self.do_loadlist(self.config['core']['list']) + self.do_loadlist(self.GetStringFromConfig('core', 'preferences', 'playlist')) def _BindEvents(self): #TODO: figure out if we can use the eventManager for menu ranges @@ -516,7 +519,7 @@ class HookeFrame(wx.Frame): filters = self.config['folders']['filters'] index = self.config['folders'].as_int('filterindex') #set initial directory - folder = self.config['core']['workdir'] + folder = self.GetStringFromConfig('core', 'preferences', 'workdir') return wx.GenericDirCtrl(self, -1, dir=folder, size=(200, 250), style=wx.DIRCTRL_SHOW_FILTERS, filter=filters, defaultFilter=index) def CreatePanelNote(self): @@ -1216,6 +1219,8 @@ class HookeFrame(wx.Frame): self.AppendToOutput('Matplotlib version: ' + mpl_version) self.AppendToOutput('SciPy version: ' + scipy_version) self.AppendToOutput('NumPy version: ' + numpy_version) + self.AppendToOutput('ConfigObj version: ' + configobj_version) + self.AppendToOutput('wxPropertyGrid version: ' + '.'.join([str(PROPGRID_MAJOR), str(PROPGRID_MINOR), str(PROPGRID_RELEASE)])) self.AppendToOutput('---') self.AppendToOutput('Platform: ' + str(platform.uname())) self.AppendToOutput('******************************') @@ -1292,19 +1297,20 @@ class HookeFrame(wx.Frame): def UpdatePlot(self, plot=None): - def add_to_plot(curve): + def add_to_plot(curve, set_scale=True): if curve.visible and curve.x and curve.y: #get the index of the subplot to use as destination destination = (curve.destination.column - 1) * number_of_rows + curve.destination.row - 1 #set all parameters for the plot axes_list[destination].set_title(curve.title) - axes_list[destination].set_xlabel(curve.multiplier.x + curve.units.x) - axes_list[destination].set_ylabel(curve.multiplier.y + curve.units.y) - #set the formatting details for the scale - formatter_x = lib.curve.PrefixFormatter(curve.decimals.x, curve.multiplier.x, use_zero) - formatter_y = lib.curve.PrefixFormatter(curve.decimals.y, curve.multiplier.y, use_zero) - axes_list[destination].xaxis.set_major_formatter(formatter_x) - axes_list[destination].yaxis.set_major_formatter(formatter_y) + if set_scale: + axes_list[destination].set_xlabel(curve.prefix.x + curve.units.x) + axes_list[destination].set_ylabel(curve.prefix.y + curve.units.y) + #set the formatting details for the scale + formatter_x = lib.curve.PrefixFormatter(curve.decimals.x, curve.prefix.x, use_zero) + formatter_y = lib.curve.PrefixFormatter(curve.decimals.y, curve.prefix.y, use_zero) + axes_list[destination].xaxis.set_major_formatter(formatter_x) + axes_list[destination].yaxis.set_major_formatter(formatter_y) if curve.style == 'plot': axes_list[destination].plot(curve.x, curve.y, color=curve.color, label=curve.label, lw=curve.linewidth, zorder=1) if curve.style == 'scatter': @@ -1322,8 +1328,8 @@ class HookeFrame(wx.Frame): curve.decimals.x = self.GetIntFromConfig('core', 'preferences', 'x_decimals') curve.decimals.y = self.GetIntFromConfig('core', 'preferences', 'y_decimals') curve.legend = self.GetBoolFromConfig('core', 'preferences', 'legend') - curve.multiplier.x = self.GetStringFromConfig('core', 'preferences', 'x_multiplier') - curve.multiplier.y = self.GetStringFromConfig('core', 'preferences', 'y_multiplier') + curve.prefix.x = self.GetStringFromConfig('core', 'preferences', 'x_prefix') + curve.prefix.y = self.GetStringFromConfig('core', 'preferences', 'y_prefix') if active_file.driver is None: self.AppendToOutput('Invalid file: ' + active_file.filename) return @@ -1340,6 +1346,7 @@ class HookeFrame(wx.Frame): figure = self.GetActiveFigure() figure.clear() + #use '0' instead of e.g. '0.00' for scales use_zero = self.GetBoolFromConfig('core', 'preferences', 'use_zero') #optionally remove the extension from the title of the plot @@ -1355,6 +1362,7 @@ class HookeFrame(wx.Frame): number_of_rows = max([curve.destination.row for curve in self.displayed_plot.curves]) for index in range(number_of_rows * number_of_columns): axes_list.append(figure.add_subplot(number_of_rows, number_of_columns, index + 1)) + #add all curves to the corresponding plots for curve in self.displayed_plot.curves: add_to_plot(curve) @@ -1366,7 +1374,7 @@ class HookeFrame(wx.Frame): self.panelResults.ClearResults() if self.displayed_plot.results.has_key(self.results_str): for curve in self.displayed_plot.results[self.results_str].results: - add_to_plot(curve) + add_to_plot(curve, set_scale=False) self.panelResults.DisplayResults(self.displayed_plot.results[self.results_str]) else: self.panelResults.ClearResults() diff --git a/lib/curve.py b/lib/curve.py index a6143c9..1a8c688 100644 --- a/lib/curve.py +++ b/lib/curve.py @@ -22,7 +22,7 @@ class Curve(object): self.label = '' self.legend = False self.linewidth = 1 - self.multiplier = Multiplier() + self.prefix = Prefix() self.size = 0.5 self.style = 'plot' self.title = '' @@ -53,7 +53,7 @@ class Destination(object): self.row = 1 -class Multiplier(object): +class Prefix(object): def __init__(self): self.x = 'n' @@ -64,9 +64,9 @@ class PrefixFormatter(Formatter): ''' Formatter (matplotlib) class that uses power prefixes. ''' - def __init__(self, decimals=2, multiplier='n', use_zero=True): + def __init__(self, decimals=2, prefix='n', use_zero=True): self.decimals = decimals - self.multiplier = multiplier + self.prefix = prefix self.use_zero = use_zero def __call__(self, x, pos=None): @@ -74,7 +74,7 @@ class PrefixFormatter(Formatter): if self.use_zero: if x == 0: return '0' - multiplier = lib.prettyformat.get_exponent(self.multiplier) + multiplier = lib.prettyformat.get_exponent(self.prefix) decimals_str = '%.' + str(self.decimals) + 'f' return decimals_str % (x / (10 ** multiplier)) diff --git a/lib/libhooke.py b/lib/libhooke.py index c377ed0..3e48f92 100644 --- a/lib/libhooke.py +++ b/lib/libhooke.py @@ -69,17 +69,6 @@ def get_file_path(filename, folders = []): filename = os.path.join(hookeDir, path, filename) return filename -def pickup_contact_point(filename=''): - ''' - Picks up the contact point by left-clicking. - ''' - contact_point = self._measure_N_points(N=1, message='Please click on the contact point.')[0] - contact_point_index = contact_point.index - self.wlccontact_point = contact_point - self.wlccontact_index = contact_point.index - self.wlccurrent = filename - return contact_point, contact_point_index - def remove_extension(filename): ''' Removes the extension from a filename. diff --git a/lib/prettyformat.py b/lib/prettyformat.py index 5ace11b..09f98b0 100644 --- a/lib/prettyformat.py +++ b/lib/prettyformat.py @@ -33,6 +33,7 @@ def pretty_format(value, unit='', decimals=-1, multiplier=0, leading_spaces=Fals leading_spaces_int = 0 if leading_spaces: leading_spaces_int = 5 + #automatic setting of multiplier if multiplier == 0: multiplier=get_multiplier(value) unit_str = '' diff --git a/lib/results.py b/lib/results.py index 644fc85..ca458bd 100644 --- a/lib/results.py +++ b/lib/results.py @@ -43,40 +43,6 @@ class Results(object): return prettyformat.pretty_format(value, '', decimals, multiplier, True) return str(value) - #def get_fit_result(self): - #if not(self.has_multipliers): - #self.set_multipliers() - - #sResult = 'Contour length ['+prettyformat.get_prefix(self.multiplierContourLength) + 'm]' + self.separator - #sResult += prettyformat.pretty_format(self.contourLength[0], '', self.decimals, self.multiplierContourLength, True) + '\n' - #sResult += 'Persistence length ['+prettyformat.get_prefix(self.multiplierPersistenceLength) + 'm]' + self.separator - #sResult += prettyformat.pretty_format(self.persistenceLength[0], '', self.decimals, self.multiplierPersistenceLength, True) + '\n' - #sResult += 'Rupture force ['+prettyformat.get_prefix(self.multiplierRuptureForce) + 'N]' + self.separator - #sResult += prettyformat.pretty_format(self.ruptureForces[0], '', self.decimals, self.multiplierRuptureForce, True) + '\n' - #sResult += 'Slope ['+prettyformat.get_prefix(self.multiplierSlope) + 'N/m]' + self.separator - #sResult += prettyformat.pretty_format(self.slopes[0], '', self.decimals, self.multiplierSlope, True)+'\n' - #sResult += 'Sigma contour ['+prettyformat.get_prefix(self.multiplierContourLength) + 'm]' + self.separator - #sResult += prettyformat.pretty_format(self.contourLengthSigma[0], '', self.decimals, self.multiplierContourLength, True) + '\n' - #sResult += 'Sigma persistence ['+prettyformat.get_prefix(self.multiplierPersistenceLength) + 'm]' + self.separator - #sResult += prettyformat.pretty_format(self.persistenceLengthSigma[0], '', self.decimals, self.multiplierPersistenceLength, True) - - #return sResult - - #def get_fit_results(self, index): - #if index >= 0 and index < len(self.contourLength): - #if not(self.has_multipliers): - #self.set_multipliers() - #sLine = prettyformat.pretty_format(self.contourLength[index], '', self.decimals, self.multiplierContourLength, True) + self.separator - #sLine += prettyformat.pretty_format(self.persistenceLength[index], '', self.decimals, self.multiplierPersistenceLength, True) + self.separator - #sLine += prettyformat.pretty_format(self.ruptureForces[index], '', self.decimals, self.multiplierRuptureForce, True) + self.separator - #sLine += prettyformat.pretty_format(self.slopes[index], '', self.decimals, self.multiplierSlope, True) + self.separator - #sLine += prettyformat.pretty_format(self.contourLengthSigma[index], '', self.decimals, self.multiplierContourLength, True) + self.separator - #sLine += prettyformat.pretty_format(self.persistenceLengthSigma[index], '', self.decimals, self.multiplierPersistenceLength, True) - - #return sLine - #else: - #return '' - def has_results(self): return len(self.results) > 0 diff --git a/plugins/autopeak.ini b/plugins/autopeak.ini index 726252a..7e7b077 100644 --- a/plugins/autopeak.ini +++ b/plugins/autopeak.ini @@ -45,12 +45,12 @@ default = automatic elements = contact point, automatic, 1 point, 2 points type = enum - value = contact point + value = automatic [[color]] default = black type = color - value = "(255,0,128)" + value = "(0,0,0)" [[delta_force]] default = 10 diff --git a/plugins/autopeak.py b/plugins/autopeak.py index 56d132e..8bed9e0 100644 --- a/plugins/autopeak.py +++ b/plugins/autopeak.py @@ -166,10 +166,10 @@ class autopeakCommands: #--Contact point arguments if reclick: - contact_point, contact_point_index = lh.pickup_contact_point(filename=filename) + contact_point, contact_point_index = self.pickup_contact_point(filename=filename) elif noauto: if self.wlccontact_index is None or self.wlccurrent != filename: - contact_point, contact_point_index = lh.pickup_contact_point(filename=filename) + contact_point, contact_point_index = self.pickup_contact_point(filename=filename) else: contact_point = self.wlccontact_point contact_point_index = self.wlccontact_index @@ -287,8 +287,7 @@ class autopeakCommands: fit_result.size = plot_size fit_result.style = plot_style fit_result.title = retraction.title - fit_result.units.x = retraction.units.x - fit_result.units.y = retraction.units.y + fit_result.units = retraction.units fit_result.visible = True fit_result.x = xfit fit_result.y = yfit @@ -304,3 +303,15 @@ class autopeakCommands: #TODO: #self.do_note('autopeak') + + def pickup_contact_point(self, filename=''): + ''' + Picks up the contact point by left-clicking. + ''' + contact_point = self._measure_N_points(N=1, message='Please click on the contact point.')[0] + contact_point_index = contact_point.index + self.wlccontact_point = contact_point + self.wlccontact_index = contact_point.index + self.wlccurrent = filename + return contact_point, contact_point_index + diff --git a/plugins/core.ini b/plugins/core.ini index 763b1a6..278b7c8 100644 --- a/plugins/core.ini +++ b/plugins/core.ini @@ -67,6 +67,21 @@ type = boolean value = False + [[playlist]] + default = playlists\test.hkp + type = filename + value = R:\Programming\Eclipse\HookeGUI\src\playlists\test1.hkp + + [[use_zero]] + default = True + type = boolean + value = True + + [[workdir]] + default = "" + type = folder + value = R:\Programming\Eclipse\HookeGUI\src + [[x_decimals]] default = 2 maximum = 10 @@ -74,7 +89,7 @@ type = integer value = 2 - [[x_multiplier]] + [[x_prefix]] default = n elements = n, p type = enum @@ -87,16 +102,11 @@ type = integer value = 2 - [[y_multiplier]] + [[y_prefix]] default = n elements = n, p type = enum value = n - - [[use_zero]] - default = True - type = boolean - value = True [copylog] [[destination]] diff --git a/plugins/curvetools.ini b/plugins/curvetools.ini deleted file mode 100644 index d3f5a12..0000000 --- a/plugins/curvetools.ini +++ /dev/null @@ -1 +0,0 @@ - diff --git a/plugins/curvetools.py b/plugins/curvetools.py deleted file mode 100644 index cd00fc6..0000000 --- a/plugins/curvetools.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -''' -curvetools.py - -General library of peak detection related functions. - -Copyright ???? by ? -with modifications by Dr. Rolf Schmidt (Concordia University, Canada) - -This program is released under the GNU General Public License version 2. -''' - -class curvetoolsCommands: - - def fit_interval_nm(self, start_index, x_vect, nm, backwards): - ''' - Calculates the number of points to fit, given a fit interval in nm - start_index: index of point - plot: plot to use - backwards: if true, finds a point backwards. - ''' - - c = 0 - i = start_index - maxlen=len(x_vect) - while abs(x_vect[i] - x_vect[start_index]) * (10**9) < nm: - if i == 0 or i == maxlen-1: #we reached boundaries of vector! - return c - if backwards: - i -= 1 - else: - i += 1 - c += 1 - return c - - def pickup_contact_point(self, filename=''): - ''' - macro to pick up the contact point by clicking - ''' - - contact_point = self._measure_N_points(N=1, message='Please click on the contact point.')[0] - contact_point_index = contact_point.index - self.wlccontact_point = contact_point - self.wlccontact_index = contact_point.index - self.wlccurrent = filename - return contact_point, contact_point_index diff --git a/plugins/export.ini b/plugins/export.ini index 9598aa4..d0b1540 100644 --- a/plugins/export.ini +++ b/plugins/export.ini @@ -7,7 +7,7 @@ [[folder]] default = "" type = folder - value = R:\Programming\Python\Gui\data\export + value = [[prefix]] default = "" @@ -28,7 +28,7 @@ [[folder]] default = "" type = folder - value = R:\Programming\Python\Gui\data\export + value = [[prefix]] default = "" @@ -74,9 +74,9 @@ value = True [[filename]] - default = fit export.txt + default = results.txt type = filename - value = R:\Programming\Python\Gui\data\export\fit export.txt + value = [[separator]] default = "," diff --git a/plugins/generalvclamp.ini b/plugins/generalvclamp.ini index f019ef5..c0e67c9 100644 --- a/plugins/generalvclamp.ini +++ b/plugins/generalvclamp.ini @@ -11,7 +11,7 @@ type = integer value = 2 - [[multiplier]] + [[prefix]] default = n elements = n, p type = enum @@ -53,7 +53,7 @@ type = integer value = 2 - [[multiplier]] + [[prefix]] default = p elements = n, p type = enum @@ -165,7 +165,7 @@ type = integer value = 20 - [[multiplier]] + [[prefix]] default = p elements = n, p type = enum diff --git a/plugins/generalvclamp.py b/plugins/generalvclamp.py index c0b5750..36b496c 100644 --- a/plugins/generalvclamp.py +++ b/plugins/generalvclamp.py @@ -6,7 +6,7 @@ generalvclamp.py Plugin regarding general velocity clamp measurements Copyright 2008 by Massimo Sandal, Fabrizio Benedetti, Marco Brucale, Bruno Samori (University of Bologna, Italy), -and Alberto Gomez-Casado (University of Twente) +and Alberto Gomez-Casado (University of Twente) with modifications by Dr. Rolf Schmidt (Concordia University, Canada) This program is released under the GNU General Public License version 2. @@ -46,8 +46,8 @@ class generalvclampCommands: ''' color = self.GetColorFromConfig('generalvclamp', 'distance', 'color') decimals = self.GetIntFromConfig('generalvclamp', 'distance', 'decimals') - multiplier_str = self.GetStringFromConfig('generalvclamp', 'distance', 'multiplier') - multiplier = lib.prettyformat.get_exponent(multiplier_str) + prefix = self.GetStringFromConfig('generalvclamp', 'distance', 'prefix') + multiplier = 10 ** lib.prettyformat.get_exponent(prefix) show = self.GetBoolFromConfig('generalvclamp', 'distance', 'show') show_in_legend = self.GetBoolFromConfig('generalvclamp', 'distance', 'show_in_legend') size = self.GetIntFromConfig('generalvclamp', 'distance', 'size') @@ -86,7 +86,7 @@ class generalvclampCommands: self.UpdatePlot(plot) - output_str = lib.prettyformat.pretty_format(abs(delta.get_delta_x()), delta.units.x, decimals, 10 ** multiplier) + output_str = lib.prettyformat.pretty_format(abs(delta.get_delta_x()), delta.units.x, decimals, multiplier) self.AppendToOutput(''.join(['Distance: ', output_str])) def do_force(self): @@ -99,8 +99,8 @@ class generalvclampCommands: ''' color = self.GetColorFromConfig('generalvclamp', 'force', 'color') decimals = self.GetIntFromConfig('generalvclamp', 'force', 'decimals') - multiplier_str = self.GetStringFromConfig('generalvclamp', 'force', 'multiplier') - multiplier = lib.prettyformat.get_exponent(multiplier_str) + prefix = self.GetStringFromConfig('generalvclamp', 'force', 'prefix') + multiplier = 10 ** lib.prettyformat.get_exponent(prefix) show = self.GetBoolFromConfig('generalvclamp', 'force', 'show') show_in_legend = self.GetBoolFromConfig('generalvclamp', 'force', 'show_in_legend') size = self.GetIntFromConfig('generalvclamp', 'force', 'size') @@ -139,7 +139,7 @@ class generalvclampCommands: self.UpdatePlot(plot) - output_str = lib.prettyformat.pretty_format(abs(delta.get_delta_y()), delta.units.y, decimals, 10 ** multiplier) + output_str = lib.prettyformat.pretty_format(abs(delta.get_delta_y()), delta.units.y, decimals, multiplier) self.AppendToOutput(''.join(['Force: ', output_str])) def do_forcebase(self): @@ -171,8 +171,8 @@ class generalvclampCommands: maximumrange_show_in_legend = self.GetBoolFromConfig('generalvclamp', 'forcebase', 'maximumrange_show_in_legend') maximumrange_size = self.GetIntFromConfig('generalvclamp', 'forcebase', 'maximumrange_size') maxpoint = self.GetBoolFromConfig('generalvclamp', 'forcebase', 'max') - multiplier_str = self.GetStringFromConfig('generalvclamp', 'forcebase', 'multiplier') - multiplier = lib.prettyformat.get_exponent(multiplier_str) + prefix = self.GetStringFromConfig('generalvclamp', 'forcebase', 'prefix') + multiplier = 10 ** lib.prettyformat.get_exponent(prefix) rebase = self.GetBoolFromConfig('generalvclamp', 'forcebase', 'rebase') whatset_str = self.GetStringFromConfig('generalvclamp', 'forcebase', 'whatset') whatset = 'retraction' @@ -269,12 +269,12 @@ class generalvclampCommands: self.UpdatePlot(plot) unit_str = plot.curves[whatset].units.y - output_str = lib.prettyformat.pretty_format(forcebase, unit_str, decimals, 10 ** multiplier) + output_str = lib.prettyformat.pretty_format(forcebase, unit_str, decimals, multiplier) self.AppendToOutput(''.join(['Force: ', output_str])) - + def plotmanip_multiplier(self, plot, current, customvalue=False): ''' - Multiplies all the Y values of an SMFS curve by a value stored in the 'force_multiplier' + Multiplies all the Y values of an SMFS curve by a value stored in the 'force_multiplier' configuration variable. Useful for calibrations and other stuff. ''' @@ -284,12 +284,12 @@ class generalvclampCommands: force_multiplier = self.GetFloatFromConfig('generalvclamp', 'force_multiplier') if force_multiplier == 1: - return plot + return plot plot.curves[lh.EXTENSION].y = [element * force_multiplier for element in plot.curves[lh.EXTENSION].y] plot.curves[lh.RETRACTION].y = [element * force_multiplier for element in plot.curves[lh.RETRACTION].y] - - return plot + + return plot def plotmanip_flatten(self, plot, current, customvalue=0): ''' diff --git a/plugins/playlist.ini b/plugins/playlist.ini index 82deb82..943e9c1 100644 --- a/plugins/playlist.ini +++ b/plugins/playlist.ini @@ -1,8 +1,13 @@ [genlist] + [[detect_mfp1d]] + default = False + type = boolean + value = True + [[folder]] default = "" type = folder - value = C:\Hooke + value = [[filemask]] default = *.* @@ -19,4 +24,4 @@ [[filename]] default = untitled.hkp type = filename - value = C:\Hooke\playlists\test.hkp + value = playlists\test.hkp diff --git a/plugins/playlist.py b/plugins/playlist.py index 41db26e..209832b 100644 --- a/plugins/playlist.py +++ b/plugins/playlist.py @@ -30,22 +30,20 @@ class playlistCommands(object): def do_genlist(self, filemask='', folder=''): ''' - GENLIST Generates a file playlist. - Note it doesn't *save* it: see savelist for this. + Note: genlist does not *save* the playlist, it only generates it. In order to save a playlist, use savelist. - If [input files] is a directory, it will use all files in the directory for playlist. - So: - genlist dir - genlist dir/ - genlist dir/*.* - - are all equivalent syntax. - ------------ - Syntax: genlist [input files] + filemask: set the filemask to use. For example, the default value '*.*' will include all files found in the playlist. + folder: set the folder in which the data that you want to analyze resides + detect_mfp1d: automatically uses '*deflection*' as filemask + MFP-1D files come in pairs (2009-10-20deflection4483.ibw and 2009-10-20LVDT4483.ibw). For the playlist to contain + only file per experiment, only deflection files are included. ''' + detect_mfp1d = self.GetBoolFromConfig('playlist', 'genlist', 'detect_mfp1d') if filemask == '': filemask = self.GetStringFromConfig('playlist', 'genlist', 'filemask') + if detect_mfp1d: + filemask = '*deflection*' if folder == '': folder = self.GetStringFromConfig('playlist', 'genlist', 'folder') if os.path.isdir(folder): diff --git a/plugins/plot.ini b/plugins/plot.ini index 0c0264e..7c1db75 100644 --- a/plugins/plot.ini +++ b/plugins/plot.ini @@ -1,8 +1,8 @@ -[plot] +[preferences] [[legend]] default = False type = boolean - value = True + value = False [[x_decimals]] default = 2 @@ -11,7 +11,7 @@ type = integer value = 2 - [[x_multiplier]] + [[x_prefix]] default = n elements = n, p type = enum @@ -22,12 +22,11 @@ maximum = 10 minimum = 0 type = integer - value = 1 + value = 2 - [[y_multiplier]] + [[y_prefix]] default = n elements = n, p type = enum value = n - diff --git a/plugins/plot.py b/plugins/plot.py index fca35ff..0e8c460 100644 --- a/plugins/plot.py +++ b/plugins/plot.py @@ -1,24 +1,24 @@ -#!/usr/bin/env python - -''' -plot.py - -Global settings for plots - -Copyright 2010 by Dr. Rolf Schmidt (Concordia University, Canada) - -This program is released under the GNU General Public License version 2. -''' - -class plotCommands: - - def do_plot(self): - active_file = self.GetActiveFile() - for curve in active_file.plot.curves: - curve.decimals.x = self.GetIntFromConfig('plot', 'x_decimals') - curve.decimals.y = self.GetIntFromConfig('plot', 'y_decimals') - curve.legend = self.GetBoolFromConfig('plot', 'legend') - curve.multiplier.x = self.GetStringFromConfig('plot', 'x_multiplier') - curve.multiplier.y = self.GetStringFromConfig('plot', 'y_multiplier') - - self.UpdatePlot(); +#!/usr/bin/env python + +''' +plot.py + +Global settings for plots + +Copyright 2010 by Dr. Rolf Schmidt (Concordia University, Canada) + +This program is released under the GNU General Public License version 2. +''' + +class plotCommands: + + def do_preferences(self): + active_file = self.GetActiveFile() + for curve in active_file.plot.curves: + curve.decimals.x = self.GetIntFromConfig('plot', 'preferences', 'x_decimals') + curve.decimals.y = self.GetIntFromConfig('plot', 'preferences', 'y_decimals') + curve.legend = self.GetBoolFromConfig('plot', 'preferences', 'legend') + curve.prefix.x = self.GetStringFromConfig('plot', 'preferences', 'x_prefix') + curve.prefix.y = self.GetStringFromConfig('plot', 'preferences', 'y_prefix') + + self.UpdatePlot(); diff --git a/plugins/procplots.py b/plugins/procplots.py index ac36993..f56010a 100644 --- a/plugins/procplots.py +++ b/plugins/procplots.py @@ -278,9 +278,8 @@ class procplotsCommands: fft_curve.destination.row = row fft_curve.label = plot.curves[index].label fft_curve.legend = True - fft_curve.multiplier.x = lib.prettyformat.get_prefix(max(fft_curve.x)) - fft_curve.multiplier.y = lib.prettyformat.get_prefix(max(fft_curve.y)) - #fft_curve.multiplier.y = '' + fft_curve.prefix.x = lib.prettyformat.get_prefix(max(fft_curve.x)) + fft_curve.prefix.y = lib.prettyformat.get_prefix(max(fft_curve.y)) fft_curve.title = 'FFT' fft_curve.units.x = 'Hz' fft_curve.units.y = 'power'