X-Git-Url: http://git.tremily.us/?a=blobdiff_plain;f=doc%2Fhacking.txt;h=e1e08c00c6671d3da91514bf379fd675fef634f7;hb=7e86490034deda4e27cda435bce5d498e8a2b997;hp=27967af0060e44a7d735f1af3123939d95c1e49b;hpb=f19a9bb458e451eec98d6fa6d1bdd7a951267c24;p=hooke.git diff --git a/doc/hacking.txt b/doc/hacking.txt index 27967af..e1e08c0 100644 --- a/doc/hacking.txt +++ b/doc/hacking.txt @@ -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 @@ -127,9 +142,61 @@ Utilities There are a number of general coding features we need for Hooke that are not provided by Python's standard library. We factor those -features out into :mod:`~hooke.utils`. +features out into :mod:`~hooke.util`. 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_*`` + =================== ==================