ctioga2 0.0 → 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/Changelog +25 -1
  2. data/lib/ctioga2/commands/commands.rb +13 -2
  3. data/lib/ctioga2/commands/doc/doc.rb +13 -17
  4. data/lib/ctioga2/commands/doc/documentation-commands.rb +14 -1
  5. data/lib/ctioga2/commands/doc/help.rb +136 -25
  6. data/lib/ctioga2/commands/doc/html.rb +56 -4
  7. data/lib/ctioga2/commands/doc/introspection.rb +45 -9
  8. data/lib/ctioga2/commands/doc/man.rb +7 -5
  9. data/lib/ctioga2/commands/doc/markup.rb +39 -12
  10. data/lib/ctioga2/commands/doc/wordwrap.rb +70 -0
  11. data/lib/ctioga2/commands/general-commands.rb +7 -4
  12. data/lib/ctioga2/commands/general-types.rb +27 -12
  13. data/lib/ctioga2/commands/interpreter.rb +2 -2
  14. data/lib/ctioga2/commands/parsers/command-line.rb +9 -5
  15. data/lib/ctioga2/commands/parsers/file.rb +5 -3
  16. data/lib/ctioga2/commands/type.rb +10 -3
  17. data/lib/ctioga2/commands/variables.rb +2 -2
  18. data/lib/ctioga2/data/backends/backend.rb +17 -15
  19. data/lib/ctioga2/data/backends/backends.rb +2 -2
  20. data/lib/ctioga2/data/backends/backends/gnuplot.rb +20 -5
  21. data/lib/ctioga2/data/backends/backends/math.rb +2 -2
  22. data/lib/ctioga2/data/backends/backends/text.rb +112 -17
  23. data/lib/ctioga2/data/backends/description.rb +10 -11
  24. data/lib/ctioga2/data/datacolumn.rb +73 -14
  25. data/lib/ctioga2/data/dataset.rb +305 -9
  26. data/lib/ctioga2/data/filters.rb +49 -1
  27. data/lib/ctioga2/data/indexed-dtable.rb +137 -0
  28. data/lib/ctioga2/data/point.rb +98 -7
  29. data/lib/ctioga2/data/stack.rb +98 -21
  30. data/lib/ctioga2/graphics/coordinates.rb +19 -2
  31. data/lib/ctioga2/graphics/elements.rb +12 -2
  32. data/lib/ctioga2/graphics/elements/containers.rb +14 -2
  33. data/lib/ctioga2/graphics/elements/contour.rb +67 -0
  34. data/lib/ctioga2/graphics/elements/curve2d.rb +103 -42
  35. data/lib/ctioga2/graphics/elements/element.rb +12 -2
  36. data/lib/ctioga2/graphics/elements/gradient-region.rb +94 -0
  37. data/lib/ctioga2/graphics/elements/parametric2d.rb +172 -0
  38. data/lib/ctioga2/graphics/elements/primitive.rb +37 -21
  39. data/lib/ctioga2/graphics/elements/region.rb +143 -0
  40. data/lib/ctioga2/graphics/elements/subplot.rb +92 -32
  41. data/lib/ctioga2/graphics/elements/tangent.rb +99 -0
  42. data/lib/ctioga2/graphics/elements/xyz-map.rb +126 -0
  43. data/lib/ctioga2/graphics/generator.rb +91 -6
  44. data/lib/ctioga2/graphics/legends.rb +26 -21
  45. data/lib/ctioga2/graphics/legends/area.rb +8 -8
  46. data/lib/ctioga2/graphics/legends/items.rb +5 -5
  47. data/lib/ctioga2/graphics/legends/storage.rb +4 -2
  48. data/lib/ctioga2/graphics/root.rb +24 -2
  49. data/lib/ctioga2/graphics/styles.rb +8 -0
  50. data/lib/ctioga2/graphics/styles/axes.rb +49 -23
  51. data/lib/ctioga2/graphics/styles/base.rb +2 -2
  52. data/lib/ctioga2/graphics/styles/carrays.rb +9 -2
  53. data/lib/ctioga2/graphics/styles/colormap.rb +272 -0
  54. data/lib/ctioga2/graphics/styles/curve.rb +64 -4
  55. data/lib/ctioga2/graphics/styles/drawable.rb +68 -9
  56. data/lib/ctioga2/graphics/styles/errorbar.rb +73 -0
  57. data/lib/ctioga2/graphics/styles/factory.rb +133 -17
  58. data/lib/ctioga2/graphics/styles/gradients.rb +60 -0
  59. data/lib/ctioga2/graphics/styles/location.rb +64 -0
  60. data/lib/ctioga2/graphics/styles/map-axes.rb +164 -0
  61. data/lib/ctioga2/graphics/styles/plot.rb +165 -62
  62. data/lib/ctioga2/graphics/styles/sets.rb +14 -1
  63. data/lib/ctioga2/graphics/styles/texts.rb +44 -34
  64. data/lib/ctioga2/graphics/subplot-commands.rb +94 -6
  65. data/lib/ctioga2/graphics/types.rb +113 -35
  66. data/lib/ctioga2/graphics/types/bijection.rb +3 -3
  67. data/lib/ctioga2/graphics/types/boundaries.rb +120 -1
  68. data/lib/ctioga2/graphics/types/dimensions.rb +8 -1
  69. data/lib/ctioga2/graphics/types/grid.rb +196 -0
  70. data/lib/ctioga2/graphics/types/location.rb +228 -0
  71. data/lib/ctioga2/graphics/types/point.rb +2 -2
  72. data/lib/ctioga2/log.rb +18 -18
  73. data/lib/ctioga2/metabuilder/type.rb +15 -3
  74. data/lib/ctioga2/metabuilder/types.rb +2 -2
  75. data/lib/ctioga2/metabuilder/types/coordinates.rb +13 -1
  76. data/lib/ctioga2/metabuilder/types/data.rb +50 -0
  77. data/lib/ctioga2/metabuilder/types/generic.rb +60 -0
  78. data/lib/ctioga2/metabuilder/types/lists.rb +53 -16
  79. data/lib/ctioga2/metabuilder/types/styles.rb +26 -45
  80. data/lib/ctioga2/plotmaker.rb +91 -20
  81. data/lib/ctioga2/postprocess.rb +8 -8
  82. data/lib/ctioga2/utils.rb +23 -4
  83. metadata +107 -75
  84. data/lib/ctioga2/data/merge.rb +0 -43
@@ -0,0 +1,272 @@
1
+ # colormap.rb: a way to map values to colors
2
+ # copyright (c) 2009 by Vincent Fourmond
3
+
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details (in the COPYING file).
13
+
14
+ require 'ctioga2/utils'
15
+ require 'ctioga2/log'
16
+
17
+ # This module contains all the classes used by ctioga
18
+ module CTioga2
19
+
20
+ Version::register_svn_info('$Revision: 199 $', '$Date: 2010-11-30 00:48:26 +0100 (Tue, 30 Nov 2010) $')
21
+
22
+ module Graphics
23
+
24
+ module Styles
25
+
26
+
27
+ # A mapping Z values -> color.
28
+ #
29
+ # It can be a simple two-point gradient, but it can also be much
30
+ # more complex.
31
+ #
32
+ # Basically, a ColorMap is a series of colors with an optional Z
33
+ # value (taken as the average of the ones around if missing) + a
34
+ # color for above and a color for below.
35
+ #
36
+ # @todo For now, ColorMap relies on the intrisic tioga color
37
+ # map, but it would be interesting to implement that "by hand"
38
+ # for the case when a byte of resolution isn't enough (which are
39
+ # going to be rare, I think)
40
+ class ColorMap
41
+
42
+ # Z values
43
+ attr_accessor :values
44
+
45
+ # Corresponding colors
46
+ attr_accessor :colors
47
+
48
+ # Colors for points of Z value below and above the limit;
49
+ # _nil_ for no specific value, :mask for masking them out
50
+ #
51
+ # @todo These are currently not implemented.
52
+ attr_accessor :below, :above
53
+
54
+ # Whether the map follows RGB (true) or HLS (false). On by
55
+ # default.
56
+ #
57
+ # It does not change anything with respect to how the colors
58
+ # are interpreted: whatever happens, the values are RGB.
59
+ attr_accessor :rgb
60
+
61
+ def initialize(values = [], colors = [])
62
+ @values = values.dup
63
+ @colors = colors.dup
64
+
65
+ @rgb = true
66
+ end
67
+
68
+ # Creates a ColorMap from a text specification of the kind:
69
+ #
70
+ # Red--Blue(1.0)--Green
71
+ #
72
+ # The specification can optionally be surrounded by colors with ::
73
+ #
74
+ # Green::Red--Blue::Orange
75
+ #
76
+ # Means that Green are for colors below, Orange for
77
+ # above. These colors can also be "cut" or "mask", meaning
78
+ # that the corresponding side isn't displayed.
79
+ def self.from_text(str)
80
+ str = str.dup
81
+ hls = false
82
+ re = /natural:?/i # Not too bad ?
83
+ if str =~ re
84
+ str.sub!(re,'')
85
+ hls = true
86
+ end
87
+
88
+ l = str.split(/::/)
89
+
90
+
91
+ if l.size == 2 # This is the complex case
92
+ if l[1] =~ /--/
93
+ l.push('')
94
+ else
95
+ l.unshift('')
96
+ end
97
+ elsif l.size == 1
98
+ l.push('')
99
+ l.unshift('')
100
+ end
101
+
102
+ ## @todo More and more I find that this metabuilder thing is
103
+ ## a little cumbersome, especially since I have an
104
+ ## additional type system on top of this one.
105
+ colortype = Commands::CommandType.get_type('color')
106
+
107
+
108
+ # Now, we have three elements
109
+ if l[0].size > 0
110
+ if l[0] =~ /mask|cut/i
111
+ below = :mask
112
+ else
113
+ below = colortype.string_to_type(l[0])
114
+ end
115
+ else
116
+ below = nil
117
+ end
118
+
119
+ if l[2].size > 0
120
+ if l[2] =~ /mask|cut/i
121
+ above = :mask
122
+ else
123
+ above = colortype.string_to_type(l[2])
124
+ end
125
+ else
126
+ above = nil
127
+ end
128
+
129
+ specs = l[1].split(/--/)
130
+
131
+ values = []
132
+ colors = []
133
+ for s in specs
134
+ if s =~ /([^(]+)\((.*)\)/
135
+ values << $2.to_f
136
+ colors << colortype.string_to_type($1)
137
+ else
138
+ values << nil
139
+ colors << colortype.string_to_type(s)
140
+ end
141
+ end
142
+ cm = ColorMap.new(values, colors)
143
+ cm.above = above
144
+ cm.below = below
145
+ cm.rgb = ! hls
146
+ return cm
147
+ end
148
+
149
+
150
+ # Prepares the 'data', 'colormap' and 'value_mask' arguments
151
+ # to t.create_image based on the given data, and the min and
152
+ # max Z levels
153
+ #
154
+ # @todo handle masking + in and out of range.
155
+ #
156
+ # @todo I don't think this function is named properly.
157
+ def prepare_data_display(t, data, zmin, zmax)
158
+ # We correct zmin and zmax
159
+ cmap, zmin, zmax = *self.to_colormap(t, zmin, zmax)
160
+
161
+ data = t.create_image_data(data.reverse_rows,
162
+ 'min_value' => zmin,
163
+ 'max_value' => zmax)
164
+
165
+ return { 'data' => data,
166
+ 'colormap' => cmap
167
+ }
168
+ end
169
+
170
+ # Returns a color triplet corresponding to the given z value
171
+ #
172
+ # @todo For now, the HSV parameter isn't honored.
173
+ def z_color(z, zmin, zmax)
174
+ zvs = z_values(zmin, zmax)
175
+
176
+ idx = zvs.where_first_ge(z)
177
+ if idx && idx > 0
178
+ x = (zvs[idx] - z)/(zvs[idx] - zvs[idx-1])
179
+ c = Utils::mix_objects(@colors[idx-1],@colors[idx], x)
180
+ # p [c, idx, z, zmin, zmax]
181
+ return c
182
+ elsif idx == 0
183
+ return @colors.first
184
+ else
185
+ return @colors.last
186
+ end
187
+ end
188
+
189
+ # Converts to a Tioga color_map
190
+ #
191
+ # @todo That won't work when there are things inside/outside
192
+ # of the map.
193
+ def to_colormap(t, zmin, zmax)
194
+
195
+ # OK. Now, we have correct z values. We just need to scale
196
+ # them between z_values[0] and z_values.last, to get a [0:1]
197
+ # interval.
198
+ zvs = z_values(zmin, zmax)
199
+ p_values = zvs.dup
200
+ p_values.sub!(p_values.first)
201
+ p_values.div!(p_values.last)
202
+
203
+ dict = {
204
+ 'points' => p_values
205
+ }
206
+ if @rgb
207
+ dict['Rs'] = []
208
+ dict['Gs'] = []
209
+ dict['Bs'] = []
210
+ for col in @colors
211
+ dict['Rs'] << col[0]
212
+ dict['Gs'] << col[1]
213
+ dict['Bs'] << col[2]
214
+ end
215
+ else
216
+ dict['Hs'] = []
217
+ dict['Ls'] = []
218
+ dict['Ss'] = []
219
+ for col in @colors
220
+ col = t.rgb_to_hls(col)
221
+ dict['Hs'] << col[0]
222
+ dict['Ls'] << col[1]
223
+ dict['Ss'] << col[2]
224
+ end
225
+ end
226
+ return [t.create_colormap(dict), zvs.first, zvs.last]
227
+ end
228
+
229
+ protected
230
+
231
+ # Returns a Dvector holding z values corresponding to each of
232
+ # the color.
233
+ #
234
+ # @todo This function will be called very often and is not
235
+ # very efficient; there should be a way to cache the results,
236
+ # either implicitly using a realy cache or explicitly by
237
+ # "instantiating" the colormap for given values of zmin and
238
+ # zmax.
239
+ #
240
+ # @todo This function doesn't ensure that the resulting z
241
+ # values are monotonic, which isn't quite that good.
242
+ def z_values(zmin, zmax)
243
+ # Real Z values.
244
+ z_values = @values.dup
245
+ z_values[0] ||= zmin
246
+ z_values[-1] ||= zmax
247
+
248
+ # Now, we replace all the nil values by the correct position
249
+ # (the middle or both around when only one _nil_ is found,
250
+ # 1/3 2/3 for 2 consecutive _nil_ values, and so on).
251
+ last_value = 0
252
+ 1.upto(z_values.size-1) do |i|
253
+ if z_values[i]
254
+ if last_value + 1 < i
255
+ (last_value+1).upto(i - 1) do |j|
256
+ frac = (j - last_value)/(i - last_value + 1.0)
257
+ p [last_value, j, i, frac]
258
+ z_values[j] = z_values[last_value] * frac +
259
+ z_values[i] * (1 - frac)
260
+ end
261
+ end
262
+ last_value = i
263
+ end
264
+ end
265
+ return Dobjects::Dvector[*z_values]
266
+ end
267
+
268
+ end
269
+
270
+ end
271
+ end
272
+ end
@@ -17,7 +17,7 @@ require 'ctioga2/log'
17
17
  # This module contains all the classes used by ctioga
18
18
  module CTioga2
19
19
 
20
- Version::register_svn_info('$Revision: 2 $', '$Date: 2009-04-25 14:03:30 +0200 (Sat, 25 Apr 2009) $')
20
+ Version::register_svn_info('$Revision: 198 $', '$Date: 2010-11-30 00:48:23 +0100 (Tue, 30 Nov 2010) $')
21
21
 
22
22
  module Graphics
23
23
 
@@ -25,7 +25,7 @@ module CTioga2
25
25
 
26
26
  # A class holding all the styles for a curve.
27
27
  #
28
- # TODO: maybe for objects different than Curve2D, a subclass of
28
+ # \todo maybe for objects different than Curve2D, a subclass of
29
29
  # CurveStyle could be used ? This way, we could have clearly
30
30
  # separated legends and the like ?
31
31
  class CurveStyle
@@ -39,6 +39,48 @@ module CTioga2
39
39
  # The text of the legend, if there is one.
40
40
  attr_accessor :legend
41
41
 
42
+ # The style of the error bars when needed, as a ErrorBarStyle.
43
+ attr_accessor :error_bar
44
+
45
+ # Filling of the curve, if applicable
46
+ attr_accessor :fill
47
+
48
+ # Details of the location of the curve, a LocationStyle object.
49
+ attr_accessor :location
50
+
51
+ # Whether in a region plot, the curve should be above or below
52
+ # the filled region.
53
+ attr_accessor :region_position
54
+
55
+ # A path style.
56
+ #
57
+ # @todo Ideas for a path tyle include
58
+ # - plain lines
59
+ # - impulses ?
60
+ # - splines
61
+ # See gnuplot help for "plot with" for inspiration.
62
+ attr_accessor :path_style
63
+
64
+ # A colormap for strokes (only for XYZ data)
65
+ #
66
+ # @todo There should be a very clear way to mark curve style
67
+ # elements which are specific to certain kinds of plots (and
68
+ # warn the user about misuses ?)
69
+ attr_accessor :color_map
70
+
71
+ # The name of an axis to create to use for the display of the
72
+ # Z scale.
73
+ #
74
+ # @todo specify the behaviour when the axis exists.
75
+ attr_accessor :zaxis
76
+
77
+ # A colormap for markers (only for XYZ data)
78
+ attr_accessor :marker_color_map
79
+
80
+ # Whether the XY display should split on NaN values (wherever)
81
+ attr_accessor :split_on_nan
82
+
83
+
42
84
  # True if a line should be drawn.
43
85
  def has_line?
44
86
  return @line && @line.style
@@ -59,12 +101,30 @@ module CTioga2
59
101
  # * 'line_...': a StrokeStyle for the drawing the line
60
102
  # * 'marker_...': a MarkerStyle for the drawing of markers
61
103
  # * 'legend': the legend of the curve
104
+ # * '[xy]axis': the name of the axis the curve should be
105
+ # plotted onto
62
106
  #
63
- # TODO: make @legend another object derived from BasicStyle ?
107
+ # \todo make #legend another object derived from BasicStyle ?
64
108
  def set_from_hash(hash)
65
109
  @line = StrokeStyle.from_hash(hash, 'line_%s')
66
110
  @marker = MarkerStyle.from_hash(hash, 'marker_%s')
111
+ @error_bar = ErrorBarStyle.from_hash(hash, 'error_bar_%s')
112
+ @location = LocationStyle.from_hash(hash, 'location_%s')
113
+ @fill = CurveFillStyle.from_hash(hash, 'fill_%s')
114
+
115
+ @region_position = hash['region_position']
116
+
67
117
  @legend = hash['legend']
118
+
119
+ @path_style = hash['style']
120
+
121
+ @color_map = hash['color_map']
122
+
123
+ @marker_color_map = hash['marker_color_map']
124
+
125
+ @split_on_nan = hash['split_on_nan']
126
+
127
+ @zaxis = hash['zaxis']
68
128
  end
69
129
 
70
130
  # Creates a CurveStyle object straight from a hash
@@ -79,7 +139,7 @@ module CTioga2
79
139
  # Draws a legend pictogram that fills up the whole current
80
140
  # frame.
81
141
  #
82
- # TODO: add more elements to the pictogram in case of more
142
+ # \todo add more elements to the pictogram in case of more
83
143
  # complex things.
84
144
  def draw_legend_pictogram(t)
85
145
  t.context do
@@ -17,7 +17,7 @@ require 'ctioga2/log'
17
17
  # This module contains all the classes used by ctioga
18
18
  module CTioga2
19
19
 
20
- Version::register_svn_info('$Revision: 61 $', '$Date: 2009-05-29 01:00:56 +0200 (Fri, 29 May 2009) $')
20
+ Version::register_svn_info('$Revision: 158 $', '$Date: 2010-07-23 15:03:47 +0200 (Fri, 23 Jul 2010) $')
21
21
 
22
22
  module Graphics
23
23
 
@@ -47,7 +47,10 @@ module CTioga2
47
47
  # This class represents all the stylistic information to draw a
48
48
  # Marker.
49
49
  #
50
- # TODO: many things are still missing here...
50
+ # \todo many things are still missing here...
51
+ #
52
+ # * in particular, angles could be handled here, and they could
53
+ # be handled directly in the marker specification...
51
54
  class MarkerStyle < BasicStyle
52
55
 
53
56
  # The color
@@ -60,27 +63,83 @@ module CTioga2
60
63
  attr_accessor :scale
61
64
 
62
65
  # Shows the marker at a given location/set of locations.
63
- def draw_markers_at(t, x, y)
64
- if x.is_a? Numeric
65
- x = Dvector[x]
66
- y = Dvector[y]
67
- end
66
+ #
67
+ # \p override is a hash that can override part of the
68
+ # dictionnary specification.
69
+ def draw_markers_at(t, x, y, override = nil)
68
70
  t.context do
69
- # Always with line style solid (though that could change ?)
71
+ ## \todo allow custom line types for markers ?
70
72
  t.line_type = LineStyles::Solid
71
73
  dict = {
72
- 'Xs' => x, 'Ys' => y,
73
74
  'marker' => @marker,
74
75
  'color' => @color
75
76
  }
77
+ if x.is_a? Numeric
78
+ dict['x'] = x
79
+ dict['y'] = y
80
+ else
81
+ dict['Xs'] = x
82
+ dict['Ys'] = y
83
+ end
84
+
76
85
  if @scale
77
86
  dict['scale'] = @scale
78
87
  end
88
+ if override
89
+ dict.merge!(override)
90
+ end
79
91
  t.show_marker(dict)
80
92
  end
81
93
  end
82
94
  end
83
95
 
96
+ # A style that handles drawing a fill.
97
+ #
98
+ # \todo add ways to specify complex fills, such as patterned
99
+ # fills and so on. Those would use clipping the path and base
100
+ # themselves on the coordinates of the current frame.
101
+ #
102
+ # \todo more attributes ?
103
+ class FillStyle < BasicStyle
104
+
105
+ # The color.
106
+ attr_accessor :color
107
+
108
+ # The transparency
109
+ attr_accessor :transparency
110
+
111
+ # Sets up the parameters for the fill. Must be called before
112
+ # any path drawing.
113
+ #
114
+ # \warning You *must* call FillStyle#do_fill for
115
+ # filling. Directly calling FigureMaker#fill is not a good
116
+ # idea, as you lose all 'hand-crafted' fills !
117
+ def setup_fill(t)
118
+ t.fill_color = @color if @color
119
+ t.fill_transparency = @transparency if @transparency
120
+ end
121
+
122
+ # Does the actual filling step. Must be used within a context,
123
+ # as it quite messes up with many things. Must be called after
124
+ # a call to #setup_fill.
125
+ def do_fill(t)
126
+ t.fill
127
+ end
128
+
129
+ end
130
+
131
+ # Same as FillStyle, but with additional parameters that handle
132
+ # how the fill should be applied to curves.
133
+ class CurveFillStyle < FillStyle
134
+
135
+ # At which Y value we should draw the horizontal line for the
136
+ # fill ? A float, or:
137
+ # * :top, :bottom
138
+ # * false, nil to disable filling altogether
139
+ attr_accessor :y0
140
+
141
+ end
142
+
84
143
  end
85
144
  end
86
145
  end