-Hooke(GUI)\r
-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.\r
-\r
-The GUI code is based on the examples from the wxPython DEMO, copyright 1997-2006 by Robin DUnn and Total Control Software.\r
+#summary Introduction to Hooke(GUI).\r
\r
-The property editor is based on the code in test_propgrid.py provided with the wxPropertyGrid download copyright 2006-2009 by Jaakko Salli.\r
+= Hooke(GUI) =\r
\r
+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.\r
\r
== Installation ==\r
-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.\r
+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.\r
Unfortunately, there seem to be some issues with wxPropertyGrid on Linux, Mac OS X and other nix systems.\r
\r
Hooke(GUI) has been developed and tested with this combination of libraries on Windows (XP, Vista, 7):\r
\r
- * Python: 2.6.4\r
- * wxPython: 2.8.10.1\r
- * wxPropertyGrid: 1.4.9.1\r
- * matplotlib: 0.99.1\r
- * SciPy: 0.7.1\r
- * NumPy: 1.3.0\r
+ * [http://www.python.org Python]: 2.6.4\r
+ * [http://www.wxpython.org wxPython]: 2.8.10.1\r
+ * [http://wxpropgrid.sourceforge.net/cgi-bin/index wxPropertyGrid]: 1.4.10\r
+ * [http://matplotlib.sourceforge.net/ matplotlib]: 0.99.1\r
+ * [http://www.scipy.org/ SciPy]: 0.7.1\r
+ * [http://www.numpy.org/ NumPy]: 1.4.0\r
+ * [http://www.voidspace.org.uk/python/configobj.html ConfigObj]: 4.6.0\r
\r
-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).\r
+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).\r
\r
-This version is not yet complete but provides the basic functionality required to do simple force curve filtering and autopeak analysis.\r
+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.\r
\r
\r
== Interface ==\r
-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):\r
+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):\r
\r
# Folders (F5)\r
# Playlists (F6)\r
# Assistant (F9)\r
# Results (F10)\r
# Output (F11)\r
+ # Note (F12)\r
\r
+http://nanoscience-dev.concordia.ca/custom/images/hooke/hooke%20gui%20screenshot.jpg\r
\r
Initially, the window will be rather small in order to work with small screen resolutions. Adjust the size and position to your liking.\r
\r
Above the windows you see the navigation toolbar to switch from one curve to another (next/previous).\r
\r
+=== Plot area ===\r
+The plot area can be customised by setting 'preferences' in the core plug-in.\r
+ * hide_curve_extension: hides the curve extension in the title of the plot (and from the playlist in the playlists panel)\r
+ * legend: show or hide the legend\r
+ * use_zero: display '0' instead of _e.g._ '0.00' on the axes\r
+ * decimals (x_decimals, y_decimals): set the decimal places for the x and y axes\r
+ * prefixes(x_prefix, y_prefix): set the prefix for the x and y axes\r
+\r
+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.\r
+\r
=== 1. Folders ===\r
-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.\r
+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).\r
\r
=== 2. Playlists ===\r
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'.\r
\r
=== 3. Commands (or Settings and commands) ===\r
-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.\r
+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.\r
\r
=== 4. Properties ===\r
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.\r
\r
=== 5. Assistant ===\r
-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\r
-default values if possible. feel free to point out missing help content.\r
+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.\r
\r
=== 6. Results ===\r
-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).\r
+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).\r
\r
=== 7. Output ===\r
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.\r
\r
+=== 8. Note ===\r
+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.\r
+\r
+\r
== General remarks ==\r
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).\r
\r
Hooke(GUI) will remember the size and position of the main window.\r
\r
-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.\r
+You can arrange the panels any which way you like and save this arrangement as a perspective.\r
+\r
+http://nanoscience-dev.concordia.ca/custom/images/hooke/hooke%20gui%20screenshot%20perspective.jpg\r
\r
-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).\r
+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.\r
+\r
+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].\r
\r
== Some plug-ins and commands ==\r
* replot (plot): replots the current force curve from scratch eliminating any secondary plots\r
* 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!\r
\r
== Basic analysis and autopeak ==\r
-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'.\r
-\r
-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.\r
+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'.\r
\r
-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).\r
+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.\r
\r
-Be advised that notes are not yet available in Hooke(GUI).\r
+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).\r
\r
== Brief Plug-in/Properties tutorial ==\r
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()).\r
-[core]\r
-list = string(default = 'test.hkp')\r
-workdir = string(default = '')\r
-\r
[drivers]\r
csvdriver = boolean(default = False)\r
hemingclamp = boolean(default = False)\r
command = autopeak\r
plugin = autopeak\r
\r
-[core]\r
-#substitute your work directory\r
-workdir = C:\hooke\r
-#the default playlist to load at startup\r
-list = playlists/test.hkp\r
-\r
#this section defines which drivers have to be loaded by Hooke\r
[drivers]\r
csvdriver = False\r
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]]
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
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
import wx.lib.evtmgr as evtmgr\r
import wx.propgrid as wxpg\r
\r
+from matplotlib.ticker import FuncFormatter\r
+\r
+from configobj import __version__ as configobj_version\r
from matplotlib import __version__ as mpl_version\r
from numpy import __version__ as numpy_version\r
from scipy import __version__ as scipy_version\r
from sys import version as python_version\r
from wx import __version__ as wx_version\r
-from matplotlib.ticker import FuncFormatter\r
+from wx.propgrid import PROPGRID_MAJOR\r
+from wx.propgrid import PROPGRID_MINOR\r
+from wx.propgrid import PROPGRID_RELEASE\r
\r
try:\r
from agw import cubecolourdialog as CCD\r
import panels.results\r
import plugins\r
\r
-import lib.igor\r
-\r
global __version__\r
global __codename__\r
global __releasedate__\r
# see the end up FrameManager::Update() for the test\r
# code. For now, just hard code a frame minimum size\r
self.SetMinSize(wx.Size(500, 500))\r
- #create panels here\r
- self.panelAssistant = self.CreatePanelAssistant()\r
- self.panelCommands = self.CreatePanelCommands()\r
- self.panelFolders = self.CreatePanelFolders()\r
- self.panelPlaylists = self.CreatePanelPlaylists()\r
- self.panelProperties = self.CreatePanelProperties()\r
- self.panelNote = self.CreatePanelNote()\r
- self.panelOutput = self.CreatePanelOutput()\r
- self.panelResults = self.CreatePanelResults()\r
- self.plotNotebook = self.CreateNotebook()\r
-\r
- # add panes\r
- self._mgr.AddPane(self.panelFolders, aui.AuiPaneInfo().Name('Folders').Caption('Folders').Left().CloseButton(True).MaximizeButton(False))\r
- self._mgr.AddPane(self.panelPlaylists, aui.AuiPaneInfo().Name('Playlists').Caption('Playlists').Left().CloseButton(True).MaximizeButton(False))\r
- self._mgr.AddPane(self.panelNote, aui.AuiPaneInfo().Name('Note').Caption('Note').Left().CloseButton(True).MaximizeButton(False))\r
- self._mgr.AddPane(self.plotNotebook, aui.AuiPaneInfo().Name('Plots').CenterPane().PaneBorder(False))\r
- self._mgr.AddPane(self.panelCommands, aui.AuiPaneInfo().Name('Commands').Caption('Settings and commands').Right().CloseButton(True).MaximizeButton(False))\r
- self._mgr.AddPane(self.panelProperties, aui.AuiPaneInfo().Name('Properties').Caption('Properties').Right().CloseButton(True).MaximizeButton(False))\r
- self._mgr.AddPane(self.panelAssistant, aui.AuiPaneInfo().Name('Assistant').Caption('Assistant').Right().CloseButton(True).MaximizeButton(False))\r
- self._mgr.AddPane(self.panelOutput, aui.AuiPaneInfo().Name('Output').Caption('Output').Bottom().CloseButton(True).MaximizeButton(False))\r
- self._mgr.AddPane(self.panelResults, aui.AuiPaneInfo().Name('Results').Caption('Results').Bottom().CloseButton(True).MaximizeButton(False))\r
- #self._mgr.AddPane(self.textCtrlCommandLine, aui.AuiPaneInfo().Name('CommandLine').CaptionVisible(False).Fixed().Bottom().Layer(2).CloseButton(False).MaximizeButton(False))\r
- #self._mgr.AddPane(panelBottom, aui.AuiPaneInfo().Name("panelCommandLine").Bottom().Position(1).CloseButton(False).MaximizeButton(False))\r
-\r
- # add the toolbars to the manager\r
- #self.toolbar=self.CreateToolBar()\r
- self.toolbarNavigation=self.CreateToolBarNavigation()\r
- #self._mgr.AddPane(self.toolbar, aui.AuiPaneInfo().Name('toolbar').Caption('Toolbar').ToolbarPane().Top().Layer(1).Row(1).LeftDockable(False).RightDockable(False))\r
- self._mgr.AddPane(self.toolbarNavigation, aui.AuiPaneInfo().Name('toolbarNavigation').Caption('Navigation').ToolbarPane().Top().Layer(1).Row(1).LeftDockable(False).RightDockable(False))\r
- # "commit" all changes made to FrameManager\r
- self._mgr.Update()\r
- #create the menubar after the panes so that the default perspective\r
- #is created with all panes open\r
- self.CreateMenuBar()\r
- self.statusbar = self.CreateStatusbar()\r
- self._BindEvents()\r
-\r
- name = self.config['perspectives']['active']\r
- menu_item = self.GetPerspectiveMenuItem(name)\r
- if menu_item is not None:\r
- self.OnRestorePerspective(menu_item)\r
- #TODO: config setting to remember playlists from last session\r
- self.playlists = self.panelPlaylists.Playlists\r
#define the list of active drivers\r
self.drivers = []\r
for driver in self.config['drivers']:\r
commands = [command for command in commands if command.startswith('do_')]\r
if commands:\r
self.plugins['core'] = commands\r
+ #create panels here\r
+ self.panelAssistant = self.CreatePanelAssistant()\r
+ self.panelCommands = self.CreatePanelCommands()\r
+ self.panelFolders = self.CreatePanelFolders()\r
+ self.panelPlaylists = self.CreatePanelPlaylists()\r
+ self.panelProperties = self.CreatePanelProperties()\r
+ self.panelNote = self.CreatePanelNote()\r
+ self.panelOutput = self.CreatePanelOutput()\r
+ self.panelResults = self.CreatePanelResults()\r
+ self.plotNotebook = self.CreateNotebook()\r
+\r
+ # add panes\r
+ self._mgr.AddPane(self.panelFolders, aui.AuiPaneInfo().Name('Folders').Caption('Folders').Left().CloseButton(True).MaximizeButton(False))\r
+ self._mgr.AddPane(self.panelPlaylists, aui.AuiPaneInfo().Name('Playlists').Caption('Playlists').Left().CloseButton(True).MaximizeButton(False))\r
+ self._mgr.AddPane(self.panelNote, aui.AuiPaneInfo().Name('Note').Caption('Note').Left().CloseButton(True).MaximizeButton(False))\r
+ self._mgr.AddPane(self.plotNotebook, aui.AuiPaneInfo().Name('Plots').CenterPane().PaneBorder(False))\r
+ self._mgr.AddPane(self.panelCommands, aui.AuiPaneInfo().Name('Commands').Caption('Settings and commands').Right().CloseButton(True).MaximizeButton(False))\r
+ self._mgr.AddPane(self.panelProperties, aui.AuiPaneInfo().Name('Properties').Caption('Properties').Right().CloseButton(True).MaximizeButton(False))\r
+ self._mgr.AddPane(self.panelAssistant, aui.AuiPaneInfo().Name('Assistant').Caption('Assistant').Right().CloseButton(True).MaximizeButton(False))\r
+ self._mgr.AddPane(self.panelOutput, aui.AuiPaneInfo().Name('Output').Caption('Output').Bottom().CloseButton(True).MaximizeButton(False))\r
+ self._mgr.AddPane(self.panelResults, aui.AuiPaneInfo().Name('Results').Caption('Results').Bottom().CloseButton(True).MaximizeButton(False))\r
+ #self._mgr.AddPane(self.textCtrlCommandLine, aui.AuiPaneInfo().Name('CommandLine').CaptionVisible(False).Fixed().Bottom().Layer(2).CloseButton(False).MaximizeButton(False))\r
+ #self._mgr.AddPane(panelBottom, aui.AuiPaneInfo().Name("panelCommandLine").Bottom().Position(1).CloseButton(False).MaximizeButton(False))\r
+\r
+ # add the toolbars to the manager\r
+ #self.toolbar=self.CreateToolBar()\r
+ self.toolbarNavigation=self.CreateToolBarNavigation()\r
+ #self._mgr.AddPane(self.toolbar, aui.AuiPaneInfo().Name('toolbar').Caption('Toolbar').ToolbarPane().Top().Layer(1).Row(1).LeftDockable(False).RightDockable(False))\r
+ self._mgr.AddPane(self.toolbarNavigation, aui.AuiPaneInfo().Name('toolbarNavigation').Caption('Navigation').ToolbarPane().Top().Layer(1).Row(1).LeftDockable(False).RightDockable(False))\r
+ # "commit" all changes made to FrameManager\r
+ self._mgr.Update()\r
+ #create the menubar after the panes so that the default perspective\r
+ #is created with all panes open\r
+ self.CreateMenuBar()\r
+ self.statusbar = self.CreateStatusbar()\r
+ self._BindEvents()\r
+\r
+ name = self.config['perspectives']['active']\r
+ menu_item = self.GetPerspectiveMenuItem(name)\r
+ if menu_item is not None:\r
+ self.OnRestorePerspective(menu_item)\r
+ #TODO: config setting to remember playlists from last session\r
+ self.playlists = self.panelPlaylists.Playlists\r
#initialize the commands tree\r
self.panelCommands.Initialize(self.plugins)\r
for command in dir(self):\r
self.plotmanipulators.append(lib.plotmanipulator.Plotmanipulator(method=getattr(self, command), command=command))\r
\r
#load default list, if possible\r
- self.do_loadlist(self.config['core']['list'])\r
+ self.do_loadlist(self.GetStringFromConfig('core', 'preferences', 'playlist'))\r
\r
def _BindEvents(self):\r
#TODO: figure out if we can use the eventManager for menu ranges\r
filters = self.config['folders']['filters']\r
index = self.config['folders'].as_int('filterindex')\r
#set initial directory\r
- folder = self.config['core']['workdir']\r
+ folder = self.GetStringFromConfig('core', 'preferences', 'workdir')\r
return wx.GenericDirCtrl(self, -1, dir=folder, size=(200, 250), style=wx.DIRCTRL_SHOW_FILTERS, filter=filters, defaultFilter=index)\r
\r
def CreatePanelNote(self):\r
self.AppendToOutput('Matplotlib version: ' + mpl_version)\r
self.AppendToOutput('SciPy version: ' + scipy_version)\r
self.AppendToOutput('NumPy version: ' + numpy_version)\r
+ self.AppendToOutput('ConfigObj version: ' + configobj_version)\r
+ self.AppendToOutput('wxPropertyGrid version: ' + '.'.join([str(PROPGRID_MAJOR), str(PROPGRID_MINOR), str(PROPGRID_RELEASE)]))\r
self.AppendToOutput('---')\r
self.AppendToOutput('Platform: ' + str(platform.uname()))\r
self.AppendToOutput('******************************')\r
\r
def UpdatePlot(self, plot=None):\r
\r
- def add_to_plot(curve):\r
+ def add_to_plot(curve, set_scale=True):\r
if curve.visible and curve.x and curve.y:\r
#get the index of the subplot to use as destination\r
destination = (curve.destination.column - 1) * number_of_rows + curve.destination.row - 1\r
#set all parameters for the plot\r
axes_list[destination].set_title(curve.title)\r
- axes_list[destination].set_xlabel(curve.multiplier.x + curve.units.x)\r
- axes_list[destination].set_ylabel(curve.multiplier.y + curve.units.y)\r
- #set the formatting details for the scale\r
- formatter_x = lib.curve.PrefixFormatter(curve.decimals.x, curve.multiplier.x, use_zero)\r
- formatter_y = lib.curve.PrefixFormatter(curve.decimals.y, curve.multiplier.y, use_zero)\r
- axes_list[destination].xaxis.set_major_formatter(formatter_x)\r
- axes_list[destination].yaxis.set_major_formatter(formatter_y)\r
+ if set_scale:\r
+ axes_list[destination].set_xlabel(curve.prefix.x + curve.units.x)\r
+ axes_list[destination].set_ylabel(curve.prefix.y + curve.units.y)\r
+ #set the formatting details for the scale\r
+ formatter_x = lib.curve.PrefixFormatter(curve.decimals.x, curve.prefix.x, use_zero)\r
+ formatter_y = lib.curve.PrefixFormatter(curve.decimals.y, curve.prefix.y, use_zero)\r
+ axes_list[destination].xaxis.set_major_formatter(formatter_x)\r
+ axes_list[destination].yaxis.set_major_formatter(formatter_y)\r
if curve.style == 'plot':\r
axes_list[destination].plot(curve.x, curve.y, color=curve.color, label=curve.label, lw=curve.linewidth, zorder=1)\r
if curve.style == 'scatter':\r
curve.decimals.x = self.GetIntFromConfig('core', 'preferences', 'x_decimals')\r
curve.decimals.y = self.GetIntFromConfig('core', 'preferences', 'y_decimals')\r
curve.legend = self.GetBoolFromConfig('core', 'preferences', 'legend')\r
- curve.multiplier.x = self.GetStringFromConfig('core', 'preferences', 'x_multiplier')\r
- curve.multiplier.y = self.GetStringFromConfig('core', 'preferences', 'y_multiplier')\r
+ curve.prefix.x = self.GetStringFromConfig('core', 'preferences', 'x_prefix')\r
+ curve.prefix.y = self.GetStringFromConfig('core', 'preferences', 'y_prefix')\r
if active_file.driver is None:\r
self.AppendToOutput('Invalid file: ' + active_file.filename)\r
return\r
\r
figure = self.GetActiveFigure()\r
figure.clear()\r
+\r
#use '0' instead of e.g. '0.00' for scales\r
use_zero = self.GetBoolFromConfig('core', 'preferences', 'use_zero')\r
#optionally remove the extension from the title of the plot\r
number_of_rows = max([curve.destination.row for curve in self.displayed_plot.curves])\r
for index in range(number_of_rows * number_of_columns):\r
axes_list.append(figure.add_subplot(number_of_rows, number_of_columns, index + 1))\r
+\r
#add all curves to the corresponding plots\r
for curve in self.displayed_plot.curves:\r
add_to_plot(curve)\r
self.panelResults.ClearResults()\r
if self.displayed_plot.results.has_key(self.results_str):\r
for curve in self.displayed_plot.results[self.results_str].results:\r
- add_to_plot(curve)\r
+ add_to_plot(curve, set_scale=False)\r
self.panelResults.DisplayResults(self.displayed_plot.results[self.results_str])\r
else:\r
self.panelResults.ClearResults()\r
self.label = ''\r
self.legend = False\r
self.linewidth = 1\r
- self.multiplier = Multiplier()\r
+ self.prefix = Prefix()\r
self.size = 0.5\r
self.style = 'plot'\r
self.title = ''\r
self.row = 1\r
\r
\r
-class Multiplier(object):\r
+class Prefix(object):\r
\r
def __init__(self):\r
self.x = 'n'\r
'''\r
Formatter (matplotlib) class that uses power prefixes.\r
'''\r
- def __init__(self, decimals=2, multiplier='n', use_zero=True):\r
+ def __init__(self, decimals=2, prefix='n', use_zero=True):\r
self.decimals = decimals\r
- self.multiplier = multiplier\r
+ self.prefix = prefix\r
self.use_zero = use_zero\r
\r
def __call__(self, x, pos=None):\r
if self.use_zero:\r
if x == 0:\r
return '0'\r
- multiplier = lib.prettyformat.get_exponent(self.multiplier)\r
+ multiplier = lib.prettyformat.get_exponent(self.prefix)\r
decimals_str = '%.' + str(self.decimals) + 'f'\r
return decimals_str % (x / (10 ** multiplier))\r
\r
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.
leading_spaces_int = 0\r
if leading_spaces:\r
leading_spaces_int = 5\r
+ #automatic setting of multiplier\r
if multiplier == 0:\r
multiplier=get_multiplier(value)\r
unit_str = ''\r
return prettyformat.pretty_format(value, '', decimals, multiplier, True)\r
return str(value)\r
\r
- #def get_fit_result(self):\r
- #if not(self.has_multipliers):\r
- #self.set_multipliers()\r
-\r
- #sResult = 'Contour length ['+prettyformat.get_prefix(self.multiplierContourLength) + 'm]' + self.separator\r
- #sResult += prettyformat.pretty_format(self.contourLength[0], '', self.decimals, self.multiplierContourLength, True) + '\n'\r
- #sResult += 'Persistence length ['+prettyformat.get_prefix(self.multiplierPersistenceLength) + 'm]' + self.separator\r
- #sResult += prettyformat.pretty_format(self.persistenceLength[0], '', self.decimals, self.multiplierPersistenceLength, True) + '\n'\r
- #sResult += 'Rupture force ['+prettyformat.get_prefix(self.multiplierRuptureForce) + 'N]' + self.separator\r
- #sResult += prettyformat.pretty_format(self.ruptureForces[0], '', self.decimals, self.multiplierRuptureForce, True) + '\n'\r
- #sResult += 'Slope ['+prettyformat.get_prefix(self.multiplierSlope) + 'N/m]' + self.separator\r
- #sResult += prettyformat.pretty_format(self.slopes[0], '', self.decimals, self.multiplierSlope, True)+'\n'\r
- #sResult += 'Sigma contour ['+prettyformat.get_prefix(self.multiplierContourLength) + 'm]' + self.separator\r
- #sResult += prettyformat.pretty_format(self.contourLengthSigma[0], '', self.decimals, self.multiplierContourLength, True) + '\n'\r
- #sResult += 'Sigma persistence ['+prettyformat.get_prefix(self.multiplierPersistenceLength) + 'm]' + self.separator\r
- #sResult += prettyformat.pretty_format(self.persistenceLengthSigma[0], '', self.decimals, self.multiplierPersistenceLength, True)\r
-\r
- #return sResult\r
-\r
- #def get_fit_results(self, index):\r
- #if index >= 0 and index < len(self.contourLength):\r
- #if not(self.has_multipliers):\r
- #self.set_multipliers()\r
- #sLine = prettyformat.pretty_format(self.contourLength[index], '', self.decimals, self.multiplierContourLength, True) + self.separator\r
- #sLine += prettyformat.pretty_format(self.persistenceLength[index], '', self.decimals, self.multiplierPersistenceLength, True) + self.separator\r
- #sLine += prettyformat.pretty_format(self.ruptureForces[index], '', self.decimals, self.multiplierRuptureForce, True) + self.separator\r
- #sLine += prettyformat.pretty_format(self.slopes[index], '', self.decimals, self.multiplierSlope, True) + self.separator\r
- #sLine += prettyformat.pretty_format(self.contourLengthSigma[index], '', self.decimals, self.multiplierContourLength, True) + self.separator\r
- #sLine += prettyformat.pretty_format(self.persistenceLengthSigma[index], '', self.decimals, self.multiplierPersistenceLength, True)\r
-\r
- #return sLine\r
- #else:\r
- #return ''\r
-\r
def has_results(self):\r
return len(self.results) > 0\r
\r
default = automatic\r
elements = contact point, automatic, 1 point, 2 points\r
type = enum\r
- value = contact point\r
+ value = automatic\r
\r
[[color]]\r
default = black\r
type = color\r
- value = "(255,0,128)"\r
+ value = "(0,0,0)"\r
\r
[[delta_force]]\r
default = 10\r
#--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
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
#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
+
type = boolean\r
value = False\r
\r
+ [[playlist]]\r
+ default = playlists\test.hkp\r
+ type = filename\r
+ value = R:\Programming\Eclipse\HookeGUI\src\playlists\test1.hkp\r
+ \r
+ [[use_zero]]\r
+ default = True\r
+ type = boolean\r
+ value = True\r
+ \r
+ [[workdir]]\r
+ default = ""\r
+ type = folder\r
+ value = R:\Programming\Eclipse\HookeGUI\src\r
+ \r
[[x_decimals]]\r
default = 2\r
maximum = 10\r
type = integer\r
value = 2\r
\r
- [[x_multiplier]]\r
+ [[x_prefix]]\r
default = n\r
elements = n, p\r
type = enum\r
type = integer\r
value = 2\r
\r
- [[y_multiplier]]\r
+ [[y_prefix]]\r
default = n\r
elements = n, p\r
type = enum\r
value = n\r
- \r
- [[use_zero]]\r
- default = True\r
- type = boolean\r
- value = True\r
\r
[copylog]\r
[[destination]]\r
+++ /dev/null
-#!/usr/bin/env python\r
-# -*- coding: utf-8 -*-\r
-\r
-'''\r
-curvetools.py\r
-\r
-General library of peak detection related functions.\r
-\r
-Copyright ???? by ?\r
-with modifications by Dr. Rolf Schmidt (Concordia University, Canada)\r
-\r
-This program is released under the GNU General Public License version 2.\r
-'''\r
-\r
-class curvetoolsCommands:\r
-\r
- def fit_interval_nm(self, start_index, x_vect, nm, backwards):\r
- '''\r
- Calculates the number of points to fit, given a fit interval in nm\r
- start_index: index of point\r
- plot: plot to use\r
- backwards: if true, finds a point backwards.\r
- '''\r
-\r
- c = 0\r
- i = start_index\r
- maxlen=len(x_vect)\r
- while abs(x_vect[i] - x_vect[start_index]) * (10**9) < nm:\r
- if i == 0 or i == maxlen-1: #we reached boundaries of vector!\r
- return c\r
- if backwards:\r
- i -= 1\r
- else:\r
- i += 1\r
- c += 1\r
- return c\r
-\r
- def pickup_contact_point(self, filename=''):\r
- '''\r
- macro to pick up the contact point by clicking\r
- '''\r
-\r
- contact_point = self._measure_N_points(N=1, message='Please click on the contact point.')[0]\r
- contact_point_index = contact_point.index\r
- self.wlccontact_point = contact_point\r
- self.wlccontact_index = contact_point.index\r
- self.wlccurrent = filename\r
- return contact_point, contact_point_index\r
[[folder]]\r
default = ""\r
type = folder\r
- value = R:\Programming\Python\Gui\data\export\r
+ value = \r
\r
[[prefix]]\r
default = ""\r
[[folder]]\r
default = ""\r
type = folder\r
- value = R:\Programming\Python\Gui\data\export\r
+ value = \r
\r
[[prefix]]\r
default = ""\r
value = True\r
\r
[[filename]]\r
- default = fit export.txt\r
+ default = results.txt\r
type = filename\r
- value = R:\Programming\Python\Gui\data\export\fit export.txt\r
+ value = \r
\r
[[separator]]\r
default = ","\r
type = integer\r
value = 2\r
\r
- [[multiplier]]\r
+ [[prefix]]\r
default = n\r
elements = n, p\r
type = enum\r
type = integer\r
value = 2\r
\r
- [[multiplier]]\r
+ [[prefix]]\r
default = p\r
elements = n, p\r
type = enum\r
type = integer\r
value = 20\r
\r
- [[multiplier]]\r
+ [[prefix]]\r
default = p\r
elements = n, p\r
type = enum\r
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.
'''
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')
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):
'''
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')
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):
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'
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]))
-
+\r
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'\r
configuration variable. Useful for calibrations and other stuff.
'''
force_multiplier = self.GetFloatFromConfig('generalvclamp', 'force_multiplier')
if force_multiplier == 1:
- return plot
+ return plot\r
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
+\r
+ return plot\r
def plotmanip_flatten(self, plot, current, customvalue=0):
'''
[genlist]\r
+ [[detect_mfp1d]]\r
+ default = False\r
+ type = boolean\r
+ value = True\r
+ \r
[[folder]]\r
default = ""\r
type = folder\r
- value = C:\Hooke\r
+ value = \r
\r
[[filemask]]\r
default = *.*\r
[[filename]]\r
default = untitled.hkp\r
type = filename\r
- value = C:\Hooke\playlists\test.hkp\r
+ value = playlists\test.hkp\r
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):
-[plot]\r
+[preferences]\r
[[legend]]\r
default = False\r
type = boolean\r
- value = True\r
+ value = False\r
\r
[[x_decimals]]\r
default = 2\r
type = integer\r
value = 2\r
\r
- [[x_multiplier]]\r
+ [[x_prefix]]\r
default = n\r
elements = n, p\r
type = enum\r
maximum = 10\r
minimum = 0\r
type = integer\r
- value = 1\r
+ value = 2\r
\r
- [[y_multiplier]]\r
+ [[y_prefix]]\r
default = n\r
elements = n, p\r
type = enum\r
value = n\r
\r
- \r
-#!/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\r
+\r
+'''\r
+plot.py\r
+\r
+Global settings for plots\r
+\r
+Copyright 2010 by Dr. Rolf Schmidt (Concordia University, Canada)\r
+\r
+This program is released under the GNU General Public License version 2.\r
+'''\r
+\r
+class plotCommands:\r
+\r
+ def do_preferences(self):\r
+ active_file = self.GetActiveFile()\r
+ for curve in active_file.plot.curves:\r
+ curve.decimals.x = self.GetIntFromConfig('plot', 'preferences', 'x_decimals')\r
+ curve.decimals.y = self.GetIntFromConfig('plot', 'preferences', 'y_decimals')\r
+ curve.legend = self.GetBoolFromConfig('plot', 'preferences', 'legend')\r
+ curve.prefix.x = self.GetStringFromConfig('plot', 'preferences', 'x_prefix')\r
+ curve.prefix.y = self.GetStringFromConfig('plot', 'preferences', 'y_prefix')\r
+\r
+ self.UpdatePlot();\r
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'