Ran update_copyright.py, updating all the copyright blurbs and adding AUTHORS.
[hooke.git] / hooke / plugin / cut.py
1 # Copyright (C) 2009-2010 Fabrizio Benedetti
2 #                         Massimo Sandal <devicerandom@gmail.com>
3 #                         W. Trevor King <wking@drexel.edu>
4 #
5 # This file is part of Hooke.
6 #
7 # Hooke is free software: you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation, either
10 # version 3 of the License, or (at your option) any later version.
11 #
12 # Hooke is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with Hooke.  If not, see
19 # <http://www.gnu.org/licenses/>.
20
21 """The `cut` module provides :class:`CutPlugin` and
22 :class:`CutCommand`.
23 """
24
25 from ..command import Command, Argument, Failure
26 from ..plugin import Plugin
27
28
29 class CutPlugin (Plugin):
30     def __init__(self):
31         super(CutPlugin, self).__init__(name='cut')
32
33     def commands(self):
34         return [CutCommand()]
35
36
37 # Define common or complicated arguments
38
39 def current_curve_callback(hooke, command, argument, value):
40     playlist = hooke.playlists.current()
41     if playlist == None:
42         raise Failure('No playlists loaded')
43     curve = playlist.current()
44     if curve == None:
45         raise Failure('No curves in playlist %s' % playlist.name)
46     return curve
47
48 CurveArgument = Argument(
49     name='curve', type='curve', callback=current_curve_callback,
50     help="""
51 :class:`hooke.curve.Curve` to cut from.  Defaults to the current curve.
52 """.strip())
53
54
55 # Define commands
56
57 class CutCommand (Command):
58     """Cut the selected signal between two points and write it to a file.
59
60     The data is saved in TAB-delimited ASCII text, where the first column
61     is "x" and the second is "y".  There is no header row.
62     """
63     def __init__(self):
64         super(CutCommand, self).__init__(
65             name='cut',
66             arguments=[
67                 CurveArgument,
68                 Argument(name='block', aliases=['set'], type='int', default=0,
69                     help="""
70 Data block to save.  For an approach/retract force curve, `0` selects
71 the approacing curve and `1` selects the retracting curve.
72 """.strip()),
73                 Argument(name='bounds', type='point', optional=False, count=2,
74                          help="""
75 Indicies of points bounding the selected data.
76 """.strip()),
77                 Argument(name='output', type='file', default='cut.dat',
78                          help="""
79 File name for the output data.
80 """.strip()),
81                 ],
82             help=self.__doc__)
83
84     def _run(self, hooke, inqueue, outqueue, params):
85         if params['curve'] == None:
86             params['curve'] = hooke.playlists.current().current()
87
88         i_min = min([p.index for p in params['points']])
89         i_max = max([p.index for p in params['points']])
90
91         data = params['curve'][params['bound']]
92         cut_data = data[i_min:i_max+1,:] # slice rows from row-major data
93         # +1 to include data[i_max] row
94
95         f = open(params['output'], 'w')
96         cut_data.tofile(f, sep='\t')
97         f.close()