ctioga2 0.0 → 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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