test/data/vclamp_jpk/README: Document sample versions
[hooke.git] / doc / hacking.txt
index b671e0572bda6fb6a5344172350aad1baa225ac0..e1e08c00c6671d3da91514bf379fd675fef634f7 100644 (file)
@@ -1,23 +1,24 @@
-*************
-Hacking Hooke
-*************
+*******
+Hacking
+*******
 
 .. toctree::
    :maxdepth: 2
 
-   testing.txt
+   testing
 
 Dependencies
 ============
 
 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_.
+any dependencies other than the `Python Standard Library`_, Numpy_,
+Scipy_, and PyYAML_.
 
 .. _Python Standard Library: http://docs.python.org/library/
 .. _Numpy: http://numpy.scipy.org/
 .. _Scipy: http://www.scipy.org/
+.. _PyYAML: http://pyyaml.org/
 
 To make a responsive user interface in parallel with data processing
 and possible GUIs, we'll use Python's multiprocessing_ module.  This
@@ -31,10 +32,24 @@ standard library, we use configparser_ for the config files.
 
 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.
+the :doc:`testing` section for more information.
 
 .. _nose: http://somethingaboutorange.com/mrl/projects/nose/0.11.3/
-.. _Testing: testing.txt
+
+
+Principles
+==========
+
+Hooke aims to be easily modified and extended by new recruits.  To
+make this easier, we try to abide by several programming practices.
+
+* `DRY`_ (Don't Repeat Yourself), also phrased as "Every piece of
+  knowledge must have a single, unambiguous, authoritative
+  representation within a system."
+* `LoD`_ (Law of Demeter): Don't reach through layers, e.g. `a.b.c.d()`.
+
+.. _DRY: http://en.wikipedia.org/wiki/Don%27t_repeat_yourself
+.. _LoD: http://en.wikipedia.org/wiki/Law_of_Demeter
 
 
 Architecture
@@ -49,7 +64,7 @@ and a :class:`~hooke.ui.UserInterface` instance to connect the
 :class:`~hooke.engine.CommandEngine` runs in a subprocess, which
 allows command execution to occur in parallel with
 :class:`~hooke.ui.UserInterface` interaction.  The two processes
-communicate via two :class:`~multiprocessing.Queue`\s.
+communicate via two :class:`multiprocessing.Queue`\s.
 
 There are a number of special classes availiable to structure queue
 communications.  See :mod:`~hooke.interaction` and
@@ -111,7 +126,7 @@ Experiments_ tags need a data-holding container to tag, and
 :class:`~hooke.curve.Data` (for example approach and retract curves in
 a :class:`~hooke.experiment.VelocityClamp` experiment would be
 seperate blocks).  :class:`~hooke.curve.Curve`\s also have an
-:attr:`~~hooke.curve.Curve.info` attribute for persistently storing
+:attr:`~hooke.curve.Curve.info` attribute for persistently storing
 arbitrary data.
 
 Playlists
@@ -133,3 +148,55 @@ There are also a number of features who's standard library support
 changes with different versions of Python.  :mod:`~hooke.compat`
 provides a uniform interface to those tools so that Hooke will work
 with several Python versions.
+
+Analysis
+--------
+
+The :class:`hooke.curve.Data` blocks store data in various states of
+processing.  For example, velocity clamp drivers will load two columns
+of data: `z piezo (m)` and `deflection (m)` (all column names have the
+`name (unit)` format, see :func:`~hooke.util.si.split_data_label`).
+Most data processing consists of manipulating current block
+information to create additional data columns in the same block.  For
+example, :class:`~hooke.plugin.vclamp.SurfaceContactCommand` usually
+uses the `z piezo (m)` and `deflection (m)` columns to add
+`surface distance (m)` and `surface adjusted deflection (m)` columns.
+However, you might want to use e.g. `median filtered deflection (m)`
+instead of `deflection (m)`.  Because of this, analysis plugins should
+use :class:`~hooke.command.Argument`\s rather than hard-coding source
+or target column or info dict names.  See
+:class:`~hooke.plugin.vclamp.SurfaceContactCommand` for an example of
+the recommended approach.
+
+Also keep in mind that some analyses will not generate columns that
+are the same size as the source data
+(e.g. :class:`~hooke.plugin.flatfilt.FlatPeaksCommand` and
+:class:`~hooke.plugin.curve.PowerSpectrumCommand`).  These commands
+will either stash information in the :class:`~hooke.curve.Data`'s
+`.info` dictionary (e.g. a list of peaks) and/or add new
+:class:`~hooke.curve.Data` blocks to the parent
+:class:`~hooke.curve.Curve`.  The main reason for adding new blocks
+rather than storing all the data in `.info` is to take advantage of
+built in :class:`~hooke.curve.Data` processing
+:class:`~hooke.command.Command`\s.  For example, the power spectrum
+from :class:`~hooke.plugin.curve.PowerSpectrumCommand` can be easily
+exported to a text file.  However, extra care must be taken to avoid
+name collisions or ambiguity, since the output blocks must be unique
+on a :class:`~hooke.curve.Curve`-wide level, while `Data.info` output
+need only be unique on a :class:`~hooke.curve.Data`-wide level.
+
+GUI
+---
+
+:mod:`hooke.ui.gui` contains enough code that you might want a word
+about its organization before diving into the code.  Information flows
+like this:
+
+.. image:: img/gui_flow/gui_flow.svg
+  
+With the following naming scheme in HookeFrame:
+
+  ===================  ==================
+  callbacks            ``_on_*``
+  response processors  ``_postprocess_*``
+  ===================  ==================