Added Sphinx documentation framework
authorW. Trevor King <wking@drexel.edu>
Thu, 6 May 2010 11:25:12 +0000 (07:25 -0400)
committerW. Trevor King <wking@drexel.edu>
Thu, 6 May 2010 11:25:12 +0000 (07:25 -0400)
14 files changed:
doc/.sconsrc-sphinx [new file with mode: 0644]
doc/SConstruct [new file with mode: 0644]
doc/USAGE [deleted file]
doc/conf.py [new file with mode: 0644]
doc/config.txt [new file with mode: 0644]
doc/doc.txt [new file with mode: 0644]
doc/generate-hooke-txt.py [new file with mode: 0644]
doc/gui.txt [moved from doc/GUI with 100% similarity]
doc/hacking.txt [new file with mode: 0644]
doc/index.txt [new file with mode: 0644]
doc/install.txt [new file with mode: 0644]
doc/testing.txt [new file with mode: 0644]
doc/tutorial.txt [new file with mode: 0644]
hooke/__init__.py

diff --git a/doc/.sconsrc-sphinx b/doc/.sconsrc-sphinx
new file mode 100644 (file)
index 0000000..bb1926a
--- /dev/null
@@ -0,0 +1 @@
+genrst = 'python generate-hooke-txt.py'
diff --git a/doc/SConstruct b/doc/SConstruct
new file mode 100644 (file)
index 0000000..fb1abe5
--- /dev/null
@@ -0,0 +1,288 @@
+"""
+This is a generic SCons script for running Sphinx (http://sphinx.pocoo.org).
+
+Type 'scons -h' for help.  This prints the available build targets on your
+system, and the configuration options you can set.
+
+If you set the 'cache' option, the option settings are cached into a file
+called '.sconsrc-sphinx' in the current directory.  When running
+subsequently, this file is reread.  A file with this name is also read from
+your home directory, if it exists, so you can put global settings there.
+
+The script looks into your 'conf.py' file for information about the
+project.  This is used in various places (e.g., to print the introductory
+message, and create package files).
+
+Here's some examples.  To build HTML docs:
+
+   scons html
+
+To create a package containing HTML and PDF docs, remembering the 'install'
+setting:
+
+   scons install=html,pdf cache=True package
+
+To clean up everything:
+
+   scons -c all
+"""
+
+# Script info.
+__author__  = "Glenn Hutchings"
+__email__   = "zondo42@googlemail.com"
+__url__     = "http://bitbucket.org/zondo/sphinx-scons"
+__license__ = "BSD"
+__version__ = "0.4"
+
+import sys, os
+
+# Build targets.
+targets = (
+    ("html",      "make standalone HTML files"),
+    ("dirhtml",   "make HTML files named index.html in directories"),
+    ("pickle",    "make pickle files"),
+    ("json",      "make JSON files"),
+    ("htmlhelp",  "make HTML files and a HTML help project"),
+    ("qthelp",    "make HTML files and a qthelp project"),
+    ("devhelp",   "make HTML files and a GNOME DevHelp project"),
+    ("epub",      "make HTML files and an EPUB file for bookreaders"),
+    ("latex",     "make LaTeX sources"),
+    ("text",      "make text file for each RST file"),
+    ("pdf",       "make PDF file from LaTeX sources"),
+    ("ps",        "make PostScript file from LaTeX sources"),
+    ("dvi",       "make DVI file from LaTeX sources"),
+    ("changes",   "make an overview over all changed/added/deprecated items"),
+    ("linkcheck", "check all external links for integrity"),
+    ("doctest",   "run all doctests embedded in the documentation if enabled"),
+    ("source",    "run a command to generate the reStructuredText source"),
+)
+
+# LaTeX builders.
+latex_builders = {"pdf": "PDF", "ps": "PostScript", "dvi": "DVI"}
+
+# List of target names.
+targetnames = [name for name, desc in targets]
+
+# Configuration cache filename.
+cachefile = ".sconsrc-sphinx"
+
+# User cache file.
+homedir = os.path.expanduser('~')
+usercache = os.path.join(homedir, cachefile)
+
+# Configuration options.
+config = Variables([usercache, cachefile], ARGUMENTS)
+
+config.AddVariables(
+    EnumVariable("default", "default build target", "html", targetnames),
+    PathVariable("config", "sphinx configuration file", "conf.py"),
+    PathVariable("srcdir", "source directory", ".",
+                 PathVariable.PathIsDir),
+    PathVariable("builddir", "build directory", "build",
+                 PathVariable.PathIsDirCreate),
+    PathVariable("doctrees", "place to put doctrees", None,
+                 PathVariable.PathAccept),
+    EnumVariable("paper", "LaTeX paper size", None,
+                 ["a4", "letter"], ignorecase = False),
+    ("tags", "comma-separated list of 'only' tags", None),
+    ("builder", "program to run to build things", "sphinx-build"),
+    ("opts", "extra builder options to use", None),
+    ListVariable("install", "targets to install", ["html"], targetnames),
+    PathVariable("instdir", "installation directory", "/usr/local/doc",
+                 PathVariable.PathAccept),
+    EnumVariable("pkgtype", "package type to build with 'scons package'",
+                 "zip", ["zip", "targz", "tarbz2"], ignorecase = False),
+    BoolVariable("cache", "whether to cache settings in %s" % cachefile, False),
+    BoolVariable("debug", "debugging flag", False),
+    ("genrst", "Command to regenerate reStructuredText source", None),
+)
+
+# Create a new environment, inheriting PATH to find builder program.  Also
+# force LaTeX instead of TeX, since the .tex file won't exist at the right
+# time to check which one to use.
+env = Environment(ENV = {"PATH" : os.environ["PATH"]},
+                  TEX = "latex", PDFTEX = "pdflatex",
+                  tools = ['default', 'packaging'],
+                  variables = config)
+
+# Get configuration values from environment.
+sphinxconf = env["config"]
+builder = env["builder"]
+default = env["default"]
+
+srcdir = env["srcdir"]
+builddir = env["builddir"]
+doctrees = env.get("doctrees", os.path.join(builddir, "doctrees"))
+
+cache = env["cache"]
+debug = env["debug"]
+
+options = env.get("opts", None)
+paper = env.get("paper", None)
+tags = env.get("tags", None)
+genrst = env.get("genrst", None)
+
+instdir = env["instdir"]
+install = env["install"]
+pkgtype = env["pkgtype"]
+
+# Dump internals if debugging.
+if debug:
+    print "Environment:"
+    print env.Dump()
+
+# Get parameters from Sphinx config file.
+sphinxparams = {}
+execfile(sphinxconf, sphinxparams)
+
+project = sphinxparams["project"]
+release = sphinxparams["release"]
+copyright = sphinxparams["copyright"]
+
+try:
+    texfilename = sphinxparams["latex_documents"][0][1]
+except KeyError:
+    texfilename = None
+
+name2tag = lambda name: name.replace(" ", "-").strip("()")
+project_tag = name2tag(project)
+release_tag = name2tag(release)
+package_tag = project_tag.lower() + "-" + release_tag.lower()
+
+# Build project description string.
+description = "%(project)s, release %(release)s, " \
+               "copyright %(copyright)s" % locals()
+
+Help(description + "\n\n")
+help_format = "   %-10s  %s\n"
+
+# Print banner if required.
+if not any(map(GetOption, ("silent", "clean", "help"))):
+    print
+    print "This is", description
+    print
+
+# Build sphinx command-line options.
+opts = []
+
+if tags:
+    opts.extend(["-t %s" % tag for tag in tags.split(",")])
+
+if paper:
+    opts.append("-D latex_paper_size=%s" % paper)
+
+if options:
+    opts.append(options)
+
+options = " ".join(opts)
+
+# Build Sphinx command template.
+sphinxcmd = """
+%(builder)s -b %(name)s -d %(doctrees)s %(options)s %(srcdir)s %(targetdir)s
+""".strip()
+
+# Set up LaTeX input builder if required.
+if texfilename:
+    latexdir = Dir("latex", builddir)
+    texinput = File(texfilename, latexdir)
+    env.SideEffect(texinput, "latex")
+    env.NoClean(texinput)
+
+# Add build targets.
+Help("Build targets:\n\n")
+
+if genrst != None:
+    source = env.Command('source', [], genrst)
+    env.AlwaysBuild(source)
+    env.Depends(srcdir, source)
+else:
+    Alias('source', srcdir)
+
+for name, desc in targets:
+    target = Dir(name, builddir)
+    targetdir = str(target)
+
+    if name == 'source':
+        pass
+    elif name not in latex_builders:
+        # Standard Sphinx target.
+        env.Command(name, sphinxconf,
+                    sphinxcmd % locals(), chdir = True)
+        env.AlwaysBuild(name)
+        env.Alias(target, name)
+    elif texinput:
+        # Target built from LaTeX sources.
+        try:
+            buildfunc = getattr(env, latex_builders[name])
+        except AttributeError:
+            continue
+
+        filename = project_tag + "." + name
+        outfile = File(filename, latexdir)
+
+        buildfunc(outfile, texinput)
+
+        # Copy built file to separate directory.
+        target = File(filename, target)
+        env.Command(target, outfile, Move(target, outfile), chdir = True)
+
+        env.Alias(name, target)
+    else:
+        continue
+
+    env.Clean(name, [target])
+    env.Clean('all', target)
+
+    if name == default: desc += " (default)"
+    Help(help_format % (name, desc))
+
+Clean('all', doctrees)
+Default(default)
+
+# Add installation targets and collect package sources.
+Help("\nOther targets:\n\n")
+
+Help(help_format % ("install", "install documentation"))
+projectdir = os.path.join(instdir, project_tag)
+sources = []
+
+for name in install:
+    source = Dir(name, builddir)
+    sources.append(source)
+
+    inst = env.Install(projectdir, source)
+    env.Alias('install', inst)
+
+    for node in env.Glob(os.path.join(str(source), '*')):
+        filename = str(node).replace(builddir + os.path.sep, "")
+        dirname = os.path.dirname(filename)
+        dest = os.path.join(projectdir, dirname)
+        inst = env.Install(dest, node)
+        env.Alias('install', inst)
+
+# Add uninstall target.
+env.Command('uninstall', None, Delete(projectdir), chdir = True)
+Help(help_format % ("uninstall", "uninstall documentation"))
+
+## Add package builder.
+#packageroot = "-".join([project_tag, release_tag])
+#archive, package = env.Package(NAME = project_tag, VERSION = release,
+#                               PACKAGEROOT = packageroot,
+#                               PACKAGETYPE = pkgtype,
+#                               source = sources)
+#
+#env.AlwaysBuild(archive)
+#env.AddPostAction(archive, Delete(packageroot))
+#Help(help_format % ("package", "build documentation package"))
+#
+#env.Clean('all', archive)
+
+# Add config settings to help.
+Help("\nConfiguration variables:")
+for line in config.GenerateHelpText(env).split("\n"):
+    Help("\n   " + line)
+
+# Save local configuration if required.
+if cache:
+    config.Update(env)
+    config.Save(cachefile, env)
diff --git a/doc/USAGE b/doc/USAGE
deleted file mode 100644 (file)
index eed629a..0000000
--- a/doc/USAGE
+++ /dev/null
@@ -1,246 +0,0 @@
-Starting Hooke
-==============
-
-Open a terminal, go to the directory Hooke is installed and type
-  python bin/hooke
-(You may need to give the full path for Python on Windows systems).
-If everything is OK, Hooke displays a nice splashscreen and starts.
-
-Once Hooke is launched from the terminal window, you see a text like
-the following:
-
-  Starting Hooke.
-  Imported plugin fit
-  Imported plugin procplots
-  Imported plugin flatfilts
-  Imported plugin generalclamp
-  Imported plugin generalvclamp
-  Imported plugin massanalysis
-  Imported plugin macro
-  Imported driver picoforce
-  Imported driver hemingclamp
-  Imported driver csvdriver
-  Imported driver tutorialdriver
-  
-  Warning: Invalid work directory.
-  This is Hooke, version 0.8.0 Seinei
-  (c) Massimo Sandal, 2006.
-  Released under the GNU General Public License Version 2.
-  Hooke is Free software.
-  ----
-  hooke:
-
-Hooke tells you that plugins and drivers have been loaded, and now
-you’re ready to go. You’re now at the Hooke command line. In the
-meantime, a splashscreen and a window with a dummy force curve should
-appear . At the command line, type "help" or "?" to obtain a list of
-available commands.
-
-hooke: ?
-Documented commands (type help <topic>):
-========================================
-addtolist debug        exit     genlist  ls   notelog previous  set
-cd         derivplot export     getlist  n    p       printlist size
-contact    dir        flatfilt jump      next plateau pwd       subtplot
-current    distance    force    loadlist note plot    savelist  wlc
-Undocumented commands:
-======================
-help
-
-hooke:
-
-
-Begin your analysis
-===================
-
-Create a playlist
------------------
-
-To start analyzing your curves, you first have to build a playlist. The
-playlist is just an index of the force curve files you want to
-analyze. Imagine it as a music playlist (that’s why it is called a
-playlist), but made of data files instead of MP3s (or FLACs :p).
-
-Suppose you have 100 PicoForce curve files in your curves directory,
-starting from mycurve.000 and ending in mycurve.100 and you want to
-analyze them all.
-
-You then can cd to the directory
-
-  hooke: cd c:\curves
-
-Type pwd to check the directory is correct
-
-  hooke: pwd
-  c:\curves
-  hooke:
-
-You can list the files in the directory using ls or dir (they’re synonims)
-
-  hooke: ls
-  [’mycurve.000’, ’mycurve.001’, ...]
-
-Now you are ready to generate the playlist. The command to use is genlist
-
-  hooke: genlist mycurve.*
-
-You can also generate a playlist containing all what you find in the
-directory by typing:
-
-  hooke: genlist c:\curves
-
-If you want to select what curves to see, based on the filename, you
-can use wildcards.
-
-  For example:
-
-  hooke: genlist mycurve.05*
-
-will take only curves from mycurve.050 to mycurve.059.
-
-Saving and loading playlists
-----------------------------
-
-Note that by using genlist you just generate the playlist in the local
-session. To save your playlist to a file, thus avoiding to regenerate
-it, type:
-
-  hooke: savelist mylist
-
-The list will be saved, in this example, in the file mylist.hkp. Hooke
-will add the extension .hkp to the playlist if you forget to. The .hkp
-file is an XML file you can read and edit with any text editor
-(i.e. Wordpad), if needed. If you want to load it, just issue loadlist
-mylist.hkp or loadlist mylist, Hooke will handle the missing .hkp
-extension. This will load the saved playlist, as if you just generated
-it.
-
-Generating the playlist, you should see the plot of the first curve
-appearing. If, generating the playlist, you are including by chance a
-non-force curve file that Hooke cannot open, it should be (more or
-less) silently ignored. If it gives some error, or it does not plot
-anything, try to navigate forward, and see if the next curve is
-plotted; it is possible you spotted a corrupted file.  Navigate the
-playlist
-
-Navigating playlists
---------------------
-
-Now you can navigate through your playlist using the command next and
-previous or, more easily, their aliases n and p. You don’t need to
-type n every time to run along a list of curves. If you press Return
-to an empty prompt, Hooke will repeat the last command you issued
-explicitly.
-
-You can also navigate through the command history by using the up and
-down arrows.
-
-When arriving to the last curve of your playlist, pressing n will just
-come back to the first. Analogously, pressing p when at the first
-curve will jump to the last.
-
-You can also jump to a given curve, this way:
-
-  hooke: jump c:\curves\mycurve.123
-
-but be careful to tell Hooke the full path to that curve, otherwise it
-will not find it.
-
-
-Taking notes
-============
-
-You can take notes about the curves you are looking at. Just type note
-followed by the text you want to append to that curve. Hooke will save
-the text in your current playlis and in an external log file. The
-output will look like this:
-
-  Notes taken at Sun Sep 17 20:42:07 2006
-  /home/cyclopia/work/tris/20060620a.041 |             This is a note
-  /home/cyclopia/work/tris/20060620a.207 |             This is another note
-  /home/cyclopia/work/tris/20060620a.286 |             This is a third one
-
-The first time you type note in a session, Hooke will ask you for a
-filename of the log.
-
-Usually curves you annotated are useful later. You can copy the curves
-you annotated in a different directory by using the copylog command,
-
-  hooke: copylog c:\nicecurves
-
-which will copy all curves you have annotated in the c:\nicecurves
-directory. Take care that the directory already exists before doing
-that.
-
-
-Exporting curves
-================
-
-You can export Hooke curves as images and as text columns. To export
-as images, issue the export command followed by the
-filename. Supported formats are PNG (raster) and EPS (Encapsulated
-Postscript, vector). The export format is determined by the filename
-extension, so export foo.png and export foo.eps will save a PNG and
-EPS file respectively.
-
-To export as text, use the txt command, followed by the filename. The
-output is a text file containing columns (first two are X and Y of
-extension, last two are X and Y of retraction).
-
-
-Interacting with the plot
-=========================
-
-Measuring distances and forces
-------------------------------
-
-You can easily zoom in the plot by dragging a rectangle on it with the
-left mouse button. To zoom out, click the right mouse
-button. Sometimes by zooming in and out too much, you can lose the
-picture (this is probably a small bug in Matplotlib). Just type plot
-at the command line and the curve will be refreshed.
-
-You can measure distances and forces directly in the plot. Just issue
-the command distance. You will be asked to click two points: do
-it. When you click a point, a blue dot should appear. When you click
-the second point, the distance (in nanometers) will apper on the
-command line. force works in the same way. You can use delta if you
-prefer, which gives meaningful values for every kind of graph (not
-only force curves). If you want to know the coordinates of a single
-point, use point.
-
-Hooke automatically adjusts the position of the clicked point at the
-nearest point in the graph, so you will be always measuring distances
-and forces between points in the graph.
-
-The commands force and distance are present in the generalvclamp.py
-plugin.
-
-Worm like chain fitting
------------------------
-
-You can measure by hand the parameters relative to a force peak using
-a worm-like chain fitting with the wlc command. The command by default
-automatically finds the contact point, asks for two points delimiting
-the portion to fit, and performs a two-variable fit, with contour
-length and persistence length as output, with relative errors. If
-desired, one can use the noauto option to manually click the contact
-point, and/or the pl=[number] options to impose a specific persistence
-length (in nanometers). Please see the help of the wlc command from
-the Hooke command line for details.
-
-Variables
----------
-
-You can set environment variables to influence the behaviour of
-Hooke. The command to use is set.
-
-You can alter permanently the behaviour of Hooke by setting these
-variables in the file conf/hooke.conf. This is a very simple XML file,
-just change the values of the variables with an ASCII text editor (not
-Word or a word processor - on Windows, Wordpad should work). Be
-careful with the correct XML syntax (which you should grasp very
-easily looking at the default configuration file) otherwise Hooke will
-crash on the next startup.
-
-See VariableList for help on individual variables.
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644 (file)
index 0000000..dd29ec5
--- /dev/null
@@ -0,0 +1,197 @@
+# -*- coding: utf-8 -*-
+#
+# sphinx-scons documentation build configuration file, created by
+# sphinx-quickstart on Thu Mar 12 10:37:15 2009.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+sys.path.insert(0, os.path.abspath('..'))
+
+import hooke
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.txt' #'.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Hooke'
+copyright = u'2006-2010, Massimo Sandal et al.'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = hooke.version(2)
+# The full version, including alpha/beta/rc tags.
+release = hooke.version(5)
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = ['build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+html_title = project + " documentation"
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+#html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'sphinx-sconsdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'hooke.tex', ur'Hooke Documentation',
+   ur'W. Trevor King', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
diff --git a/doc/config.txt b/doc/config.txt
new file mode 100644 (file)
index 0000000..6f0359b
--- /dev/null
@@ -0,0 +1,44 @@
+*****************
+Configuring Hooke
+*****************
+
+Hooke initializes a number of variables by reading configuration
+files.
+
+Syntax
+------
+
+Hooke uses Python's configparser_ library to read the config files.
+The format is similar to MS Windows' INI (initialization) format::
+
+    [My Section]
+    foo = bar
+    baz = 5
+
+.. _configparser: http://docs.python.org/library/configparser.html
+
+Examples
+--------
+
+Run::
+
+    $ hooke --example-config-file
+
+To print a well commented example config file to stdout.
+
+
+Finding configuration files
+---------------------------
+
+The default search path follows the `Filesystem Hierarchy
+Standard`_, and so will probably need adjustment for non-*nix systems.
+The default path list is
+
+* /usr/share/hooke/hooke.cfg
+* /etc/hooke/hooke.cfg
+* ~/.hooke.cfg
+
+but alternatives can be specified from the command line launching
+Hooke.
+
+_ ..Filesystem Hierarchy Standard: http://www.pathname.com/fhs/
diff --git a/doc/doc.txt b/doc/doc.txt
new file mode 100644 (file)
index 0000000..319fe4d
--- /dev/null
@@ -0,0 +1,28 @@
+****************************
+Producing this documentation
+****************************
+
+This documentation is written in reStructuredText_, and produced using
+Sphinx_ and the numpydoc_ extension.  The documentation source should
+be fairly readable without processing, but to compile the
+documentation, change to the ``doc/`` directory and run::
+
+    $ scons
+
+For which you'll need to install Sphinx, numpydoc, and SCons_::
+
+    $ easy_install Sphinx
+    $ easy_install numpydoc
+
+.. _Sphinx: http://sphinx.pocoo.org/
+.. _numpydoc: http://pypi.python.org/pypi/numpydoc
+.. _SCons: http://www.scons.org/
+
+See the reStructuredText quick reference and the `NumPy/SciPy
+documentation guide`_ for an introduction to the documentation
+syntax.
+
+.. _reStructuredText:
+  http://docutils.sourceforge.net/docs/user/rst/quickref.html
+.. _NumPy/SciPy documentation guide:
+  http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines
diff --git a/doc/generate-hooke-txt.py b/doc/generate-hooke-txt.py
new file mode 100644 (file)
index 0000000..0f7dd5c
--- /dev/null
@@ -0,0 +1,320 @@
+#!/usr/bin/python
+#
+# COPYRIGHT
+
+"""Auto-generate reStructuredText of the hooke module tree for Sphinx.
+
+This script is adapted from one written for `Bugs Everywhere`_.
+
+.. _Bugs Everywhere: http://bugseverywhere.org/
+"""
+
+import sys
+import os, os.path
+
+
+sys.path.insert(0, os.path.abspath('..'))
+
+
+def title(modname):
+    t = ':mod:`%s`' % modname
+    delim = '*'*len(t)
+    return '\n'.join([delim, t, delim, '', ''])
+
+def automodule(modname):
+    return '\n'.join([
+            '.. automodule:: %s' % modname,
+            '   :members:',
+            '   :undoc-members:',
+            '', ''])
+
+def toctree(children):
+    if len(children) == 0:
+        return ''
+    return '\n'.join([
+            '.. toctree::',
+            '   :maxdepth: 2',
+            '',
+            ] + [
+            '   %s.txt' % c for c in sorted(children)
+            ] + ['', ''])
+
+def make_module_txt(modname, children):
+    filename = os.path.join('hooke', '%s.txt' % modname)
+    if not os.path.exists('hooke'):
+        os.mkdir('hooke')
+    if os.path.exists(filename):
+        return None # don't overwrite potentially hand-written files.
+    f = file(filename, 'w')
+    f.write(title(modname))
+    f.write(automodule(modname))
+    f.write(toctree(children))
+    f.close()
+
+
+
+class Tree(list):
+    """A traversable tree structure.
+
+    Examples
+    --------
+
+    Construct::
+
+               +-b---d-g
+             a-+   +-e
+               +-c-+-f-h-i
+
+    with
+
+    >>> i = Tree();       i.n = "i"
+    >>> h = Tree([i]);    h.n = "h"
+    >>> f = Tree([h]);    f.n = "f"
+    >>> e = Tree();       e.n = "e"
+    >>> c = Tree([f,e]);  c.n = "c"
+    >>> g = Tree();       g.n = "g"
+    >>> d = Tree([g]);    d.n = "d"
+    >>> b = Tree([d]);    b.n = "b"
+    >>> a = Tree();       a.n = "a"
+    >>> a.append(c)
+    >>> a.append(b)
+
+    Get the longest branch length with
+
+    >>> a.branch_len()
+    5
+
+    Sort the tree recursively.  Here we sort longest branch length
+    first.
+
+    >>> a.sort(key=lambda node : -node.branch_len())
+    >>> "".join([node.n for node in a.traverse()])
+    'acfhiebdg'
+
+    And here we sort shortest branch length first.
+
+    >>> a.sort(key=lambda node : node.branch_len())
+    >>> "".join([node.n for node in a.traverse()])
+    'abdgcefhi'
+
+    We can also do breadth-first traverses.
+
+    >>> "".join([node.n for node in a.traverse(depth_first=False)])
+    'abcdefghi'
+
+    Serialize the tree with depth marking branches.
+
+    >>> for depth,node in a.thread():
+    ...     print "%*s" % (2*depth+1, node.n)
+    a
+      b
+        d
+          g
+      c
+        e
+        f
+          h
+            i
+
+    Flattening the thread disables depth increases except at
+    branch splits.
+
+    >>> for depth,node in a.thread(flatten=True):
+    ...     print "%*s" % (2*depth+1, node.n)
+    a
+      b
+      d
+      g
+    c
+      e
+    f
+    h
+    i
+
+    We can also check if a node is contained in a tree.
+
+    >>> a.has_descendant(g)
+    True
+    >>> c.has_descendant(g)
+    False
+    >>> a.has_descendant(a)
+    False
+    >>> a.has_descendant(a, match_self=True)
+    True
+    """
+    def __cmp__(self, other):
+        return cmp(id(self), id(other))
+
+    def __eq__(self, other):
+        return self.__cmp__(other) == 0
+
+    def __ne__(self, other):
+        return self.__cmp__(other) != 0
+
+    def branch_len(self):
+        """Return the largest number of nodes from root to leaf (inclusive).
+
+        For the tree::
+
+               +-b---d-g
+             a-+   +-e
+               +-c-+-f-h-i
+
+        this method returns 5.
+
+        Notes
+        -----
+        Exhaustive search every time == *slow*.
+
+        Use only on small trees, or reimplement by overriding
+        child-addition methods to allow accurate caching.
+        """
+        if len(self) == 0:
+            return 1
+        else:
+            return 1 + max([child.branch_len() for child in self])
+
+    def sort(self, *args, **kwargs):
+        """Sort the tree recursively.
+
+        This method extends :meth:`list.sort` to Trees.
+
+        Notes
+        -----
+        This method can be slow, e.g. on a :meth:`branch_len` sort,
+        since a node at depth `N` from the root has it's
+        :meth:`branch_len` method called `N` times.
+        """
+        list.sort(self, *args, **kwargs)
+        for child in self:
+            child.sort(*args, **kwargs)
+
+    def traverse(self, depth_first=True):
+        """Generate all the nodes in a tree, starting with the root node.
+
+        Parameters
+        ----------
+        depth_first : bool
+          Depth first by default, but you can set `depth_first` to
+          `False` for breadth first ordering.  Siblings are returned
+          in the order they are stored, so you might want to
+          :meth:`sort` your tree first.
+        """
+        if depth_first == True:
+            yield self
+            for child in self:
+                for descendant in child.traverse():
+                    yield descendant
+        else: # breadth first, Wikipedia algorithm
+            # http://en.wikipedia.org/wiki/Breadth-first_search
+            queue = [self]
+            while len(queue) > 0:
+                node = queue.pop(0)
+                yield node
+                queue.extend(node)
+
+    def thread(self, flatten=False):
+        """Generate a (depth, node) tuple for every node in the tree.
+
+        When `flatten` is `False`, the depth of any node is one
+        greater than the depth of its parent.  That way the
+        inheritance is explicit, but you can end up with highly
+        indented threads.
+
+        When `flatten` is `True`, the depth of any node is only
+        greater than the depth of its parent when there is a branch,
+        and the node is not the last child.  This can lead to ancestry
+        ambiguity, but keeps the total indentation down.  For example::
+
+                      +-b                  +-b-c
+                    a-+-c        and     a-+
+                      +-d-e-f              +-d-e-f
+
+        would both produce (after sorting by :meth:`branch_len`)::
+
+            (0, a)
+            (1, b)
+            (1, c)
+            (0, d)
+            (0, e)
+            (0, f)
+
+        """
+        stack = [] # ancestry of the current node
+        if flatten == True:
+            depthDict = {}
+
+        for node in self.traverse(depth_first=True):
+            while len(stack) > 0 \
+                    and id(node) not in [id(c) for c in stack[-1]]:
+                stack.pop(-1)
+            if flatten == False:
+                depth = len(stack)
+            else:
+                if len(stack) == 0:
+                    depth = 0
+                else:
+                    parent = stack[-1]
+                    depth = depthDict[id(parent)]
+                    if len(parent) > 1 and node != parent[-1]:
+                        depth += 1
+                depthDict[id(node)] = depth
+            yield (depth,node)
+            stack.append(node)
+
+    def has_descendant(self, descendant, depth_first=True, match_self=False):
+        """Check if a node is contained in a tree.
+
+        Parameters
+        ----------
+        descendant : Tree
+          The potential descendant.
+        depth_first : bool
+          The search order.  Set this if you feel depth/breadth would
+          be a faster search.
+        match_self : bool
+          Set to `True` for::
+
+              x.has_descendant(x, match_self=True) -> True
+        """
+        if descendant == self:
+            return match_self
+        for d in self.traverse(depth_first):
+            if descendant == d:
+                return True
+        return False
+
+
+def python_tree(root_path='hooke', root_modname='hooke'):
+    tree = Tree()
+    tree.path = root_path
+    tree.parent = None
+    stack = [tree]
+    while len(stack) > 0:
+        f = stack.pop(0)
+        if f.path.endswith('.py'):
+            f.name = os.path.basename(f.path)[:-len('.py')]
+        elif os.path.isdir(f.path) \
+                and os.path.exists(os.path.join(f.path, '__init__.py')):
+            f.name = os.path.basename(f.path)
+            f.is_module = True
+            for child in os.listdir(f.path):
+                if child == '__init__.py':
+                    continue
+                c = Tree()
+                c.path = os.path.join(f.path, child)
+                c.parent = f
+                stack.append(c)
+        else:
+            continue
+        if f.parent == None:
+            f.modname = root_modname
+        else:
+            f.modname = f.parent.modname + '.' + f.name
+            f.parent.append(f)
+    return tree
+
+if __name__ == '__main__':
+    pt = python_tree(root_path='../hooke', root_modname='hooke')
+    for node in pt.traverse():
+        make_module_txt(node.modname, [c.modname for c in node])
similarity index 100%
rename from doc/GUI
rename to doc/gui.txt
diff --git a/doc/hacking.txt b/doc/hacking.txt
new file mode 100644 (file)
index 0000000..86e969b
--- /dev/null
@@ -0,0 +1,34 @@
+*************
+Hacking Hooke
+*************
+
+
+Architecture
+============
+
+To clean up the internals, were going to go crazy on the
+object-oriented front, and try to keep the core functionality free of
+any dependencies other than the `Python Standard Library`_ and `Numpy`_
+/ `Scipy`_.
+
+.. _Python Standard Library: http://docs.python.org/library/
+.. _Numpy: http://numpy.scipy.org/
+.. _Scipy: http://www.scipy.org/
+
+To make a responsive user interface in parallel with data processing
+and possible GUIs, we'll use Python's multiprocessing_ and queue_
+modules.  These modules are both new in Python 2.6, but 2.6 usage is
+becoming fairly widespread.  Certainly more widespread than any
+alternative queue module that I know of.  Since we're leveraging the
+power of the standard library, we use configparser_ for the config
+files.
+
+.. _multiprocessing: http://docs.python.org/dev/library/multiprocessing.html
+.. _queue: http://docs.python.org/library/queue.html
+.. _configparser: http://docs.python.org/library/configparser.html
+
+On the testing side, the need to stick to the standard library relaxes
+(developers can install extra packages), so we can use nose_.  See
+the `Testing`_ section for more information.
+
+.. _Testing: testing.txt
diff --git a/doc/index.txt b/doc/index.txt
new file mode 100644 (file)
index 0000000..cb6b97b
--- /dev/null
@@ -0,0 +1,78 @@
+Welcome to the Hooke documentation!
+===================================
+
+Hooke_ is software for the (semiautomatic) analysis and filtering of
+force curves.  Force curves are the output of an analytical technique
+called `force spectroscopy`_.  Force spectroscopy experiments usually
+require the analysis of thousands of force curves at a time. As of
+today, there is no standard, free software for the analysis of force
+curves. Hooke aims to solve that.
+
+.. _Hooke: http://code.google.com/p/hooke/
+.. _force spectroscopy: http://en.wikipedia.org/wiki/Force_spectroscopy
+
+Features:
+
+* View, annotate, and measure force curves
+* Worm-like chain and freely-jointed chain fits of force peaks
+* Automatic convolution-based filtering of empty curves
+* Automatic fit and measurement of multiple force peaks
+* Handles force-clamp force experiments (experimental)
+* Extensible by users by mean of plugins and drivers 
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   install.txt
+   tutorial.txt
+   hacking.txt
+   hooke/hooke.txt
+   doc.txt
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
+Publications
+============
+
+Hooke has been published [1]. Please cite Hooke if you use it.  Let us
+know, and we'll link to your paper!
+
+
+[1] Sandal M, Benedetti F, Brucale M, Gomez-Casado A, Samorì B.,
+  "Hooke: an open software platform for force spectroscopy."
+  Bioinformatics, 2009.
+  doi: `10.1093/bioinformatics/btp180 <http://dx.doi.org/10.1093/bioinformatics/btp180>`_
+
+
+Troubleshooting
+===============
+
+If you have troubles in using Hooke:
+
+1. Search the `issue tracker`_.
+2. Look at the `trouble shooting wiki page`_.
+3. Search the `discussion group`_.
+3. Ask a question in the discussion group.
+4. File a bug on the issue tracker.
+
+.. _issue tracker: http://code.google.com/p/hooke/issues/list
+.. _trouble shooting wiki page:
+   http://code.google.com/p/hooke/wiki/TroubleShooting
+.. _discussion group: http://groups.google.com/group/hookesoftware
+
+
+Disclaimer
+==========
+
+Remember that Hooke is still experimental software! It has been mostly
+done to fit the needs of its authors, and there is no guarantee it
+will do what you need. However, you can write us/help us improve it so
+that it does. We aim to make of Hooke a little, universal tool that
+can help your research.
diff --git a/doc/install.txt b/doc/install.txt
new file mode 100644 (file)
index 0000000..a8b754c
--- /dev/null
@@ -0,0 +1,77 @@
+****************
+Installing Hooke
+****************
+
+Dependencies
+============
+
+Hooke is routinely run successfully on Windows and Linux based
+systems. It is possible to run it happily on Mac OS X too (though
+install can be a bit trickier). Technically, Hooke should run wherever
+the Python_ programming language is installed.
+
+You'll need the following Python modules:
+
+* Numpy_
+* Scipy_
+* Matplotlib_ (for generating plots)
+* wxPython_ (for the GUI)
+
+.. Numpy: http://numpy.scipy.org/
+.. Scipy: http://www.scipy.org/
+.. Python: http://www.python.org/
+.. Matplotlib: http://matplotlib.sourceforge.net/
+.. wxPython: http://www.wxpython.org/
+
+Getting the source
+==================
+
+Hooke_ is available as an Subversion_ repository::
+
+    $ svn checkout http://hooke.googlecode.com/svn/trunk/ hooke
+
+There is also a `GUI fork`_ (Rolf Schmidt)::
+
+    $ svn checkout http://hooke.googlecode.com/svn/trunk/ hooke
+
+And a `fork`_ versioned in Git_ (W. Trevor King)::
+
+    $ git clone http://www.physics.drexel.edu/~wking/code/git/hooke.git/ hooke
+
+There are also periodic bundled releases.  See the homepage for each
+fork for details.  For example, get the most recent snapshot of
+Trevor's fork in zip form with::
+
+     $ wget -o hooke.zip http://www.physics.drexel.edu/~wking/code/git/git.php?p=hooke.git&dl=zip&h=HEAD
+     $ unzip hooke.zip
+
+.. _Hooke: http://code.google.com/p/hooke/
+.. _GUI fork: http://code.google.com/p/hooke/wiki/HookeGUI
+.. _fork: http://www.physics.drexel.edu/~wking/code/git/git.php?p=hooke.git
+.. _Subversion: http://subversion.tigris.org/
+.. _Git: http://git-scm.com/
+
+
+Installation
+============
+
+Run::
+
+    $ python setup.py install
+
+to install Hooke.  Run::
+
+    $ python setup.py install --help
+
+to see a list of installation options you may want to configure.
+
+Running Hooke from the source directory
+=======================================
+
+If you like, you can avoid installation by running Hooke directly from
+it's source directory::
+
+     $ wget -o hooke.zip http://www.physics.drexel.edu/~wking/code/git/git.php?p=hooke.git&dl=zip&h=HEAD
+     $ unzip hooke.zip
+     $ cd hooke
+     $ python bin/hooke
diff --git a/doc/testing.txt b/doc/testing.txt
new file mode 100644 (file)
index 0000000..1f5ded4
--- /dev/null
@@ -0,0 +1,25 @@
+*************
+Testing Hooke
+*************
+
+Hooke's test framework is build using doctest_, unittest_, and nose_.
+``nosetests`` (from the ``nose`` package) scans through the source
+tree, searching out the various tests and running them.  If you aren't
+familiar with ``nose``, there is excellent documentation on its home
+page.  We use ``nose`` because its auto-discovery allows us to avoid
+collecting all of our assorted tests into ``unittest.TestSuite``\s and
+running them by hand.
+
+To run the test suite from the Hooke installation directory, just use::
+
+    nosetests --with-doctest --doctest-tests
+
+.. _doctest: http://docs.python.org/library/doctest.html
+.. _unittest: http://docs.python.org/library/unittest.html
+.. _nose: http://somethingaboutorange.com/mrl/projects/nose/0.11.3/
+
+
+Adding tests to modules
+-----------------------
+
+Just go crazy with doctests and unittests; ``nose`` will find them.
diff --git a/doc/tutorial.txt b/doc/tutorial.txt
new file mode 100644 (file)
index 0000000..1158aad
--- /dev/null
@@ -0,0 +1,294 @@
+********
+Tutorial
+********
+
+`A short video showing Hooke in action`_! (courtesy of Fabrizio
+Benedetti, EPFL, Lausanne)
+
+.. _A short video showing Hooke in action:
+  https://documents.epfl.ch/users/f/fb/fbenedet/www/hooke_short_demostration.ogv
+
+Introduction
+============
+
+This tutorial will focus on the command-line interface as the most
+powerful, and leave the GUI interface to another document.
+
+.. _command-line: `Command-line interface`_
+.. _GUI: gui.txt
+
+Installation
+============
+
+See the Installation_ page for details on downloading and installing
+Hooke.
+
+.. _Installation: install.txt
+
+
+Command-line interface
+======================
+
+Running the hooke shell
+-----------------------
+
+Hooke has a set of commands that depend on the loaded plugins_.
+To access these commands, you'll need to run the Hooke shell.::
+
+    $ hooke
+
+If you are running hooke from the source directory (see
+Installation_), the equivalent command is::
+
+    $ python bin/hooke
+
+You may need to give the full path for Python on Windows systems.
+
+As Hooke launches, you should see something like the following in your
+terminal::
+
+    Starting Hooke.
+    Imported plugin fit
+    Imported plugin procplots
+    Imported plugin flatfilts
+    Imported plugin generalclamp
+    Imported plugin generalvclamp
+    Imported plugin massanalysis
+    Imported plugin macro
+    Imported driver picoforce
+    Imported driver hemingclamp
+    Imported driver csvdriver
+    Imported driver tutorialdriver
+    
+    Warning: Invalid work directory.
+    This is Hooke, version 0.8.0 Seinei
+    (c) Massimo Sandal, 2006. Released under the GNU General Public License Version 2
+    Hooke is Free software.
+    ----
+    hooke>
+
+The final line, ``hooke>``, is the Hooke prompt.  It allows you to
+enter commans to interact with the interpreter.
+
+Help
+----
+
+All commands have help text explaining their purpose and usage.  The
+text is stored in the code itself, and therefore more likely to be up
+to date than this tutorial.  You can get a list of commands and topics
+with::
+
+    hooke> help
+
+Or see specific help on ``TOPIC`` with::
+
+    hooke> help TOPIC
+
+for example::
+
+    hooke> help current
+
+will give help on the ``current`` command.
+
+Creating a playlist
+-------------------
+
+To start analyzing your curves, you first have to build a playlist. The
+playlist is just an index of the force curve files you want to
+analyze. Imagine it as a music playlist (that’s why it is called a
+playlist), but with data files instead of audio files.
+
+Suppose you have 100 PicoForce curve files in your curves directory,
+starting from ``mycurve.000`` and ending in ``mycurve.100`` and you
+want to analyze them all.
+
+You then can ``cd`` (change directory) to the directory::
+
+    hooke> cd c:\curves
+
+Type ``pwd`` (print working directory) to check the directory is correct.::
+
+      hooke> pwd
+      c:\curves
+
+You can list the files in the directory using ``ls`` or ``dir`` (they’re
+synonyms).::
+
+    hooke> ls
+    [’mycurve.000’, ’mycurve.001’, ...
+    ]
+
+Now you are ready to generate the playlist. The command to use is
+``genlist``.::
+
+    hooke> genlist mycurve.*
+
+You can also generate a playlist containing all what you find in the
+directory by typing:
+
+    hooke> genlist c:\curves
+
+If you want to select what curves to see, based on the filename, you
+can use wildcards.  For example::
+
+    hooke> genlist mycurve.05*
+
+will take only curves from mycurve.050 to mycurve.059.
+
+Note that by using ``genlist`` you just generate the playlist in the
+local session. To save your playlist to a file for future reuse,
+type::
+
+    hooke> savelist mylist
+
+In this example, the list will be saved in the file ``mylist.hkp``.
+Hooke will add the extension ``.hkp`` (Hooke playlist) to the playlist
+if you forget to.  The ``.hkp`` file is an XML file you can read and
+edit with any text editor (i.e. Wordpad), if needed.  If you want to
+load it, simply issue ``loadlist mylist.hkp`` or ``loadlist mylist``,
+Hooke will add ``.hkp`` if necessary.
+
+If, generating the playlist, you are including by chance a non-force
+curve file that Hooke cannot open, Hooke will print an error and
+continue on.
+
+Navigating the playlist
+-----------------------
+
+Now you can navigate through your playlist using the commands ``next``
+and ``previous`` or, their aliases ``n`` and ``p``. You don’t need to
+type ``n`` every time to run along a list of curves.  If you press
+Return to an empty prompt, Hooke will repeat the last command you
+issued explicitly.  You can also navigate through the command history
+by using the up and down arrows.  From the last curve of your
+playlist, ``n`` will wrap around to the first curve.  Analogously,
+issuing ``p`` at the first curve will jump to the last.
+
+You can also jump to a given curve::
+
+    hooke> jump c:\curves\mycurve.012
+
+where the path can be either an absolute path, or a path relative to
+the directory holding the playlist file.
+
+Taking notes
+------------
+
+You can take notes about the curves you are looking at.  Just type
+``note`` followed by the text you want to append to that curve.  Hooke
+will save the text in your current playlist and in an external log
+file.  The output will look like this:
+
+Notes taken at Sun Sep 17 20:42:07 2006
+/home/cyclopia/work/tris/20060620a.041 |             This is a note
+/home/cyclopia/work/tris/20060620a.207 |             This is another note
+/home/cyclopia/work/tris/20060620a.286 |             This is a third one
+
+The log file name can be configured_, but it defaults to hooke.log.
+
+.. _configured: config.txt
+
+Usually curves you annotated are useful later.  You can copy the curves
+you annotated to a different directory by using the ``copylog``
+command.
+
+    hooke> copylog c:\nicecurves
+
+will copy all curves you have annotated to the c:\nicecurves
+directory.  Make sure that the directory already exists before doing
+that.  TODO: replace with::
+
+    hooke> copylist --log c:\curves\nice.hkp
+
+Exporting curves
+----------------
+
+You can export Hooke curves as images and as text columns. To export
+as images, issue the ``export`` command followed by the filename.
+Supported formats are PNG (raster) and EPS (Encapsulated Postscript,
+vectorial).  The export format is determined by the filename
+extension, so ``export foo.png`` and ``export foo.eps`` will save
+PNG and EPS files respectively.
+
+To export as text, use the ``txt`` command, followed by the
+filename. The output is a text file containing columns (first two are
+X and Y of extension, second two are X and Y of retraction).
+
+TODO: multiple cycles?  Solution: blank lines for "breaks", add option
+to extract specific sections using Python's slice notation.
+
+
+Interacting with the plot (no plots in command line mode...)
+-------------------------
+
+Measuring distances and forces
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can easily zoom in the plot by dragging a rectangle on it with the
+left mouse button.  To zoom out, click the right mouse
+button. Sometimes by zooming in and out too much, you can lose the
+picture (this is probably a small bug in Matplotlib).  Just type
+``plot`` at the command line and the curve will be refreshed.
+
+You can measure distances and forces directly in the plot. Just issue
+the command ``distance``.  You will be asked to click two points.
+When you click a point, a blue dot should appear.  When you click the
+second point, the distances (in nanometers and piconewtons) will
+appear on the command line.  You can use ``delta`` if you prefer,
+which gives meaningful values for every kind of graph (not only force
+curves). If you want to know the coordinates of a single point, use
+``point``.
+
+Hooke automatically adjusts the position of the clicked point to the
+nearest point in the graph, so you will be always measuring distances
+and forces between points in the graph.
+
+The commands ``force`` and ``distance`` are present in the
+``generalvclamp`` plugin.
+
+Worm like chain and freely jointed chain fitting
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can measure by hand the parameters relative to a force peak using
+a worm-like chain fitting with the ``fit`` command.  The command by
+default automatically finds the contact point, asks for two points
+delimiting the portion to fit, and performs a two-variable fit, with
+contour length, persistence length, and their relative errors as
+output.  If desired, one can use the ``noauto`` option to manually
+click the contact point, and/or the ``pl=NUMBER`` options to impose a
+specific persistence or Kuhn length (in nanometers). You can choose
+which model to use with ``set fit_function wlc`` or ``set fit_function
+fjc``.  See the help of the ``fit`` command from the Hooke
+command line for details.
+
+Multiple curve fitting and measuring
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can cycle through all your current playlist obtaining WLC fit, FJC
+fit, rupture force and slope (loading rate) information from each
+curve using the ``multifit`` command.  The collected data can be saved
+in a text file for further analysis in your favourite spreadsheet or
+statistical program.  If you want to check your parameters on the
+current curve before fitting all the files in your playlist, use
+``multifit justone``.  See the ``multifit`` help for more options.
+
+Fast curve reviewing and saving
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When automatic routines are not good enough to filter your data, use
+``review`` command to cycle through your playlist presenting ten
+curves in the same graph.  You can then enter the numbers of the
+interesting curves and automatically save a copy of them into another
+directory.
+
+Configuring Hooke
+-----------------
+
+You can set environment variables to influence the behaviour of
+Hooke. The command to use is ``set``.
+
+You can alter permanently the behaviour of Hooke by setting these
+variables in a Hooke configuration file.  See the `Configuring Hooke`_
+section for details.
+
+.. _Configuring Hooke: config.txt
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..694887e6bc884a28e36fc6f3f18ba94629b08644 100644 (file)
@@ -0,0 +1,75 @@
+"""The hooke module does all the legwork for Hooke_ (BE).
+
+.. _hooke: http://code.google.com/p/hooke/
+
+To facilitate faster loading, submodules are not imported by default.
+The available submodules are:
+
+* :mod:`hooke.config`
+* :mod:`hooke.compat`
+"""
+
+__version__ = (0, 9, 0, 'devel', None, 'Kenzo')
+"""Version tuple::
+
+    (major, minor, release, type, patch, name)
+
+Where 
+
+  * type: Python uses alpha, beta, candidate, and final.  Whatever
+    so long as the alphabetic sort gets them in the right order.
+  * patch: either manually incremented for each release, the packaging
+    date string, YYYYMMDD, date of last commit, whatever.
+
+See `Greg Noel's post on scons-devel`_ for a good explaination of why this
+versioning scheme is a good idea.
+
+.. _Greg Noel's post on scons-devel
+  http://thread.gmane.org/gmane.comp.programming.tools.scons.devel/8740
+"""
+
+def version(depth=-1, version_tuple=None):
+    """Return a nicely formatted version string.::
+
+        major.minor.release.type[.patch] (name)
+
+    Examples
+    --------
+
+    Since I seem to be unable to override __version__ in a Doctest,
+    we'll pass the version tuple in as an argument.  You can ignore
+    ``version_tuple``.
+
+    >>> v = (1, 2, 3, 'devel', '20100501', 'Kenzo')
+
+    If depth -1, a full version string is returned
+
+    >>> version(depth=-1, version_tuple=v)
+    '1.2.3.devel.20100501 (Kenzo)'
+
+    Otherwise, only the first depth fields are used.
+
+    >>> version(depth=3, version_tuple=v)
+    '1.2.3'
+    >>> version(depth=4, version_tuple=v)
+    '1.2.3.devel'
+
+    Here's an example dropping the patch.
+
+    >>> v = (1, 2, 3, 'devel', None, 'Kenzo')
+    >>> version(depth=-1, version_tuple=v)
+    '1.2.3.devel (Kenzo)'
+    """
+    if version_tuple == None:
+        version_tuple = __version__
+    patch_index = 4
+    if version_tuple[patch_index] == None: # No patch field, drop that entry
+        version_tuple = version_tuple[0:patch_index] \
+            + version_tuple[patch_index+1:]
+        if depth >= patch_index:
+            depth -= 1
+    fields = version_tuple[0:depth]
+    string = '.'.join([str(x) for x in fields])
+    if depth == -1 or depth == len(version_tuple):
+        string += ' (%s)' % version_tuple[-1]
+    return string