ctioga 1.11.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 (103) hide show
  1. data/COPYING +340 -0
  2. data/ctioga/bin/ctable +28 -0
  3. data/ctioga/bin/ctioga +37 -0
  4. data/ctioga/doc/ctable.1 +156 -0
  5. data/ctioga/doc/ctioga.1 +2363 -0
  6. data/ctioga/examples/README +46 -0
  7. data/ctioga/examples/ctioga.gnuplot +4 -0
  8. data/ctioga/examples/ctioga_within_tioga.rb +53 -0
  9. data/ctioga/examples/ctiogarc.rb +24 -0
  10. data/ctioga/examples/include_1.rb +15 -0
  11. data/ctioga/examples/noise.dat +100 -0
  12. data/ctioga/examples/noise.rb +13 -0
  13. data/ctioga/examples/trig.csv +100 -0
  14. data/ctioga/examples/trig.dat +100 -0
  15. data/ctioga/examples/trig.rb +14 -0
  16. data/ctioga/examples/trigh.dat +100 -0
  17. data/ctioga/examples/trigh.rb +10 -0
  18. data/ctioga/examples/tutorial +763 -0
  19. data/ctioga/examples/tutorial.sh +269 -0
  20. data/ctioga/tests/README +14 -0
  21. data/ctioga/tests/axes.sh +40 -0
  22. data/ctioga/tests/basic.sh +11 -0
  23. data/ctioga/tests/draw.sh +24 -0
  24. data/ctioga/tests/histograms.sh +14 -0
  25. data/ctioga/tests/insets.sh +41 -0
  26. data/ctioga/tests/layouts.sh +29 -0
  27. data/ctioga/tests/legends.sh +113 -0
  28. data/ctioga/tests/styles.sh +43 -0
  29. data/ctioga/tests/test_style.sh +8 -0
  30. data/ctioga/tests/tests.sh +24 -0
  31. data/ctioga/tests/text_backend.sh +83 -0
  32. data/ctioga/tests/tioga_defaults.rb +18 -0
  33. data/lib/CTioga/axes.rb +904 -0
  34. data/lib/CTioga/backends.rb +88 -0
  35. data/lib/CTioga/boundaries.rb +224 -0
  36. data/lib/CTioga/ctable.rb +134 -0
  37. data/lib/CTioga/curve_style.rb +246 -0
  38. data/lib/CTioga/debug.rb +199 -0
  39. data/lib/CTioga/dimension.rb +133 -0
  40. data/lib/CTioga/elements.rb +17 -0
  41. data/lib/CTioga/elements/base.rb +84 -0
  42. data/lib/CTioga/elements/containers.rb +578 -0
  43. data/lib/CTioga/elements/curves.rb +368 -0
  44. data/lib/CTioga/elements/tioga_primitives.rb +440 -0
  45. data/lib/CTioga/layout.rb +595 -0
  46. data/lib/CTioga/legends.rb +29 -0
  47. data/lib/CTioga/legends/cmdline.rb +187 -0
  48. data/lib/CTioga/legends/item.rb +164 -0
  49. data/lib/CTioga/legends/style.rb +257 -0
  50. data/lib/CTioga/log.rb +73 -0
  51. data/lib/CTioga/movingarrays.rb +131 -0
  52. data/lib/CTioga/partition.rb +271 -0
  53. data/lib/CTioga/plot_style.rb +230 -0
  54. data/lib/CTioga/plotmaker.rb +1677 -0
  55. data/lib/CTioga/shortcuts.rb +69 -0
  56. data/lib/CTioga/structures.rb +82 -0
  57. data/lib/CTioga/styles.rb +140 -0
  58. data/lib/CTioga/themes.rb +581 -0
  59. data/lib/CTioga/themes/classical.rb +82 -0
  60. data/lib/CTioga/themes/demo.rb +63 -0
  61. data/lib/CTioga/themes/fits.rb +91 -0
  62. data/lib/CTioga/themes/mono.rb +33 -0
  63. data/lib/CTioga/tioga.rb +32 -0
  64. data/lib/CTioga/utils.rb +173 -0
  65. data/lib/MetaBuilder/Parameters/dates.rb +38 -0
  66. data/lib/MetaBuilder/Parameters/lists.rb +132 -0
  67. data/lib/MetaBuilder/Parameters/numbers.rb +69 -0
  68. data/lib/MetaBuilder/Parameters/strings.rb +86 -0
  69. data/lib/MetaBuilder/Parameters/styles.rb +75 -0
  70. data/lib/MetaBuilder/Qt4/Parameters/dates.rb +51 -0
  71. data/lib/MetaBuilder/Qt4/Parameters/numbers.rb +65 -0
  72. data/lib/MetaBuilder/Qt4/Parameters/strings.rb +106 -0
  73. data/lib/MetaBuilder/Qt4/parameter.rb +172 -0
  74. data/lib/MetaBuilder/Qt4/parameters.rb +9 -0
  75. data/lib/MetaBuilder/descriptions.rb +603 -0
  76. data/lib/MetaBuilder/factory.rb +101 -0
  77. data/lib/MetaBuilder/group.rb +57 -0
  78. data/lib/MetaBuilder/metabuilder.rb +10 -0
  79. data/lib/MetaBuilder/parameter.rb +374 -0
  80. data/lib/MetaBuilder/parameters.rb +11 -0
  81. data/lib/MetaBuilder/qt4.rb +8 -0
  82. data/lib/SciYAG/Backends/backend.rb +379 -0
  83. data/lib/SciYAG/Backends/binner.rb +168 -0
  84. data/lib/SciYAG/Backends/cache.rb +102 -0
  85. data/lib/SciYAG/Backends/dataset.rb +158 -0
  86. data/lib/SciYAG/Backends/descriptions.rb +469 -0
  87. data/lib/SciYAG/Backends/filters.rb +25 -0
  88. data/lib/SciYAG/Backends/filters/average.rb +134 -0
  89. data/lib/SciYAG/Backends/filters/cumulate.rb +37 -0
  90. data/lib/SciYAG/Backends/filters/filter.rb +70 -0
  91. data/lib/SciYAG/Backends/filters/norm.rb +39 -0
  92. data/lib/SciYAG/Backends/filters/smooth.rb +63 -0
  93. data/lib/SciYAG/Backends/filters/sort.rb +43 -0
  94. data/lib/SciYAG/Backends/filters/strip.rb +34 -0
  95. data/lib/SciYAG/Backends/filters/trim.rb +64 -0
  96. data/lib/SciYAG/Backends/gnuplot.rb +131 -0
  97. data/lib/SciYAG/Backends/math.rb +108 -0
  98. data/lib/SciYAG/Backends/mdb.rb +462 -0
  99. data/lib/SciYAG/Backends/multitext.rb +96 -0
  100. data/lib/SciYAG/Backends/source.rb +64 -0
  101. data/lib/SciYAG/Backends/text.rb +339 -0
  102. data/lib/SciYAG/backends.rb +16 -0
  103. metadata +191 -0
@@ -0,0 +1,73 @@
1
+ # log.rb, copyright (c) 2006 by Vincent Fourmond:
2
+ # The general logging functions for Ctioga
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 'logger'
15
+ require 'forwardable'
16
+
17
+ module CTioga
18
+
19
+ Version::register_svn_info('$Revision: 653 $', '$Date: 2007-11-15 21:58:42 +0100 (Thu, 15 Nov 2007) $')
20
+
21
+ # This module contains code to be included by PlotMaker for debugging.
22
+ # Even if it doesn't deserve a real module of it's own, it makes sense
23
+ # to have it separated anyway.
24
+ module Log
25
+
26
+ extend Forwardable
27
+ def_delegators :@@log, :debug, :warn, :info, :error, :fatal
28
+
29
+ def init_logger(stream = STDERR)
30
+ Logger::Formatter::Format.replace("[%4$s] %6$s\n")
31
+ @@log = Logger.new(stream)
32
+ @@log.level = Logger::WARN # Warnings and more only by default
33
+ end
34
+
35
+ # Simple accessor for the @@log class variable.
36
+ def logger
37
+ return @@log
38
+ end
39
+
40
+ def logger_options(opt)
41
+ opt.on("-v", "--verbose", "Display useful information") do
42
+ @@log.level = Logger::INFO
43
+ end
44
+ opt.on("--debug", "Turn on debugging info") do
45
+ @@log.level = Logger::DEBUG
46
+ end
47
+ opt.on("--quiet", "Display only errors") do
48
+ @@log.level = Logger::ERROR
49
+ end
50
+ end
51
+
52
+ # A logging replacement for system
53
+ def spawn(cmd, priority = :info)
54
+ retval = system(cmd)
55
+ self.send(priority, "Running #{cmd} -> " +
56
+ if retval
57
+ "success"
58
+ else
59
+ "failure"
60
+ end
61
+ )
62
+ return retval
63
+ end
64
+
65
+ # Returns a string suitable for identification of an object, but
66
+ # without instance variables.
67
+ def identify(obj)
68
+ return "#<#{obj.class} 0x%x>" % obj.object_id
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,131 @@
1
+ # movingarray.rb, copyright (c) 2007 by Vincent Fourmond:
2
+ # Moving arrays
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 'Dobjects/Dvector'
15
+ require 'Tioga/FigureConstants'
16
+
17
+
18
+ module CTioga
19
+
20
+ Version::register_svn_info('$Revision: 854 $', '$Date: 2008-11-27 23:21:51 +0100 (Thu, 27 Nov 2008) $')
21
+
22
+ # A helper function that converts user input into a Tioga
23
+ # color.
24
+ #
25
+ # TODO: allow designs such as in LaTeX xcolor: Red!10!Blue !
26
+ def self.get_tioga_color(str)
27
+ if str =~ /([\d.]+),([\d.]+),([\d.]+)/ # Array notation
28
+ color = Dobjects::Dvector.new([$1.to_f,$2.to_f,$3.to_f])
29
+ if color.max > 1
30
+ color *= 1.0/255.0
31
+ end
32
+ return color.to_a
33
+ elsif str =~ /#([0-9a-fA-F]{6})/ # HTML notation
34
+ return $1.scan(/../).map { |i| i.to_i(16)/255.0 }
35
+ else
36
+ return Tioga::FigureConstants.const_get(str)
37
+ end
38
+ end
39
+
40
+ # This class is just a means to make an instance of Array stand out
41
+ class SpecialArray < Array
42
+ end
43
+
44
+
45
+ # The MovingArray class provides a way to scroll through an array,
46
+ # such as a set of colors, markers, linstyles, and so on. The class
47
+ # provides a way to set the value directly as well, and to forget it.
48
+ class MovingArray
49
+ include Tioga
50
+
51
+ def initialize(sets, current = nil, startpoint = 0)
52
+ @sets = sets
53
+
54
+ # Pick the first key as a default
55
+ current = @sets.keys.first unless current
56
+ choose_current_set(current)
57
+
58
+ @current_point = startpoint # the current point in the current set
59
+ end
60
+
61
+ def value
62
+ @current_point += 1
63
+ if @current_point >= @current_set.length
64
+ @current_point %= @current_set.length
65
+ end
66
+ return @current_set[@current_point - 1]
67
+ end
68
+
69
+ # Chooses the current set. If the name refers to an existing set,
70
+ # this one is chosen. If not, and if the name looks like a gradient
71
+ # specification, we interpret it as such. In any other case,
72
+ # the chosen set is the set containing only the argument. This way,
73
+ # to get a set containing a single color, you can use
74
+ #
75
+ # choose_current_set(Pink)
76
+ def choose_current_set(name)
77
+ @current_set_name = name
78
+ if @sets.key?(name)
79
+ @current_set_name = name
80
+ @current_set = @sets[name]
81
+ elsif name =~ /gradient:(.+)--(.+),(\d+)/
82
+ # Special case for color gradients
83
+ s = CTioga.get_tioga_color($1)
84
+ e = CTioga.get_tioga_color($2)
85
+ nb = $3.to_i
86
+ fact = if nb > 1
87
+ 1.0/(nb - 1) # The famous off-by one...
88
+ else
89
+ warn "Incorrect gradient number: #{nb}"
90
+ 1.0
91
+ end
92
+ array = []
93
+ nb.times do |i|
94
+ a = []
95
+ f = i * fact
96
+ e.each_index do |c|
97
+ a << s[c] * (1 - f) + e[c] * f
98
+ end
99
+ array << a
100
+ end
101
+ @current_set = array
102
+ else
103
+ if name.is_a? SpecialArray
104
+ @current_set = name
105
+ else
106
+ @current_set = [name]
107
+ end
108
+ end
109
+ end
110
+
111
+ # Returns the available sets.
112
+ def available_sets
113
+ return @sets.keys
114
+ end
115
+
116
+ # Tells whether the given name is a valid set. Takes care of the special
117
+ # case of gradients.
118
+ #
119
+ # TODO: this looks hackish, somehow, but I don't see a way to make
120
+ # that less so...
121
+ def valid_set?(name)
122
+ if name =~ /^gradient:/
123
+ return true
124
+ else
125
+ return @sets.key? name
126
+ end
127
+ end
128
+
129
+ end
130
+
131
+ end
@@ -0,0 +1,271 @@
1
+ # partition.rb: segment partitioning functions
2
+ # Copyright (c) 2008 by Vincent Fourmond
3
+
4
+
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details (in the COPYING file).
14
+
15
+ require 'CTioga/utils'
16
+
17
+
18
+ module CTioga
19
+
20
+ Version::register_svn_info('$Revision: 792 $', '$Date: 2008-05-23 00:19:31 +0200 (Fri, 23 May 2008) $')
21
+
22
+ # A module for small convenience functions.
23
+ module Utils
24
+
25
+ # The following code is stolen from SciYAG/lib/utils.rb,
26
+ # and is used to partition segments in natural-looking
27
+ # subdivisions.
28
+
29
+
30
+ # Our natural way to split decades
31
+ NaturalDistances = Dobjects::Dvector[1, 2, 2.5, 5, 10]
32
+
33
+ # Attempts to partition the given segment in at most _nb_
34
+ # segments of equal size. The segments don't necessarily start on
35
+ # the edge of the original segment
36
+ def self.partition_segment(min, max, nb)
37
+ if min > max
38
+ return partition_segment(max, min, nb)
39
+ elsif min.nan? or max.nan?
40
+ return [0] * nb
41
+ elsif min == max
42
+ return self.partition_segment(min * 0.7, min * 1.3, nb)
43
+ end
44
+ distance = max - min
45
+ min_distance = distance/(nb + 1.0) # Why + 1.0 ? To account
46
+ # for the space that could be left on the side.
47
+
48
+ # The order of magnitude of the distance:
49
+ order = min_distance.log10.floor
50
+
51
+ # A distance which is within [1, 10 [ (but the latter is never reached.
52
+ normalized_distance = min_distance * 10**(-order)
53
+ final_distance = NaturalDistances.min_gt(normalized_distance) *
54
+ 10**(order)
55
+ # puts "Distance: #{distance} in #{nb} : #{normalized_distance} #{final_distance}"
56
+
57
+ # We're getting closer now: we found the natural distance between
58
+ # ticks.
59
+
60
+ start = (min/final_distance).ceil * final_distance
61
+ retval = []
62
+ val = start
63
+ while val <= max
64
+ retval << val
65
+ # I use this to avoid potential cumulative addition
66
+ # rounding errors
67
+ val = start + final_distance * retval.size
68
+ end
69
+ return retval
70
+
71
+ end
72
+
73
+ # Our natural way to split decades - except that all successive
74
+ # element now divide each other.
75
+ NaturalDistancesNonLinear = Dobjects::Dvector[1, 2.5, 5, 10]
76
+
77
+ # A class that handles a "natural distance". Create it by giving
78
+ # the initial distance. You can then get its value, lower it,
79
+ # increase it, find the first/last element of an interval that is
80
+ # a multiple if it
81
+ class NaturalDistance
82
+
83
+ # Creates the biggest 'natural distance' that is smaller
84
+ # than _distance_
85
+ def initialize(distance)
86
+ @order = distance.log10.floor
87
+ normalized = distance * 10**(-@order)
88
+ @index = 0
89
+ for dist in NaturalDistances
90
+ if dist > normalized
91
+ break
92
+ else
93
+ @index += 1
94
+ end
95
+ end
96
+ end
97
+
98
+ # Returns the actual value of the distance
99
+ def value
100
+ return NaturalDistances[@index] * 10**(@order)
101
+ end
102
+
103
+ # Goes to the natural distance immediately under the current one
104
+ def decrease
105
+ if @index > 0
106
+ @index -= 1
107
+ else
108
+ @index = NaturalDistances.size - 1
109
+ @order -= 1
110
+ end
111
+ end
112
+
113
+ # Goes to the natural distance immediately under the current one
114
+ def increase
115
+ if @index < NaturalDistances.size - 1
116
+ @index += 1
117
+ else
118
+ @index = 0
119
+ @order += 1
120
+ end
121
+ end
122
+
123
+ # Find the minimum element inside the given interval
124
+ # that is a multiple of this distance
125
+ def find_minimum(x1, x2)
126
+ x1,x2 = x2, x1 if x1 > x2
127
+
128
+ dist = value
129
+ v = (x1/dist).ceil * dist
130
+ if v <= x2
131
+ return v
132
+ else
133
+ return false
134
+ end
135
+ end
136
+
137
+ # Returns the value of the next decade (ascending)
138
+ def next_decade(x)
139
+ decade = 10.**(@order + 1)
140
+ if @index == 0 # We stop at 0.5 if the increase is 0.5
141
+ decade *= 0.5
142
+ end
143
+ nb = Float((x/decade).ceil)
144
+ if nb == x/decade
145
+ return (nb + 1)*decade
146
+ else
147
+ return nb * decade
148
+ end
149
+ end
150
+
151
+ # Returns the number of elements to #next_decade
152
+ def nb_to_next_decade(x)
153
+ dist = value
154
+ dec = next_decade(x)
155
+ return dec/dist - (x/dist).ceil + 1
156
+ end
157
+
158
+ # Returns a list of all the values corresponding to
159
+ # the distance
160
+ def to_next_decade(x)
161
+ next_decade = next_decade(x)
162
+ dist = value
163
+ start = (x/dist).ceil * dist
164
+ retval = []
165
+ while start + retval.size * dist <= next_decade
166
+ retval << start + retval.size * dist
167
+ end
168
+ return retval
169
+ end
170
+
171
+ end
172
+
173
+
174
+ # Attempts to partition the segment image of _min_, _max_
175
+ # by the Proc object _to_ into at most _nb_ elements. The
176
+ # reverse of the transformation, _from_, has to be provided.
177
+ def self.partition_nonlinear(to, from, x1, x2, nb)
178
+ x1, x2 = x2, x1 if x1 > x2
179
+ if x1.nan? or x2.nan?
180
+ return [0] * nb
181
+ elsif x1 == x2 # Nothing to do
182
+ return self.partition_segment(x1 * 0.7, x2 * 1.3, nb)
183
+ end
184
+
185
+ xdist = x2 - x1
186
+ xdist_min = xdist/(nb + 1.0) # Why + 1.0 ? To account
187
+ # for the space that could be left on the side.
188
+
189
+ y1 = to.call(x1)
190
+ y2 = to.call(x2)
191
+
192
+ # Make sure y1 < y2
193
+ y1, y2 = y2, y1 if y1 > y2
194
+
195
+ # We first need to check if the linear partitioning of
196
+ # the target segment could be enough:
197
+
198
+ candidate = self.partition_segment(y1, y2, nb)
199
+ candidate_real = candidate.map(&from)
200
+
201
+ # We inspect the segment: if one of the length deviates from the
202
+ # average expected by more than 25%, we drop it
203
+
204
+ length = []
205
+ p candidate_real, xdist_min
206
+ 0.upto(candidate.size - 2) do |i|
207
+ length << (candidate_real[i+1] - candidate_real[i]).abs/(xdist_min)
208
+ end
209
+ p length
210
+ # If everything stays within 25% off, we keep that
211
+ if length.min > 0.75 and length.max < 1.7
212
+ return candidate
213
+ end
214
+
215
+
216
+ # We start with a geometric measure of the distance, that
217
+ # will most likely scale better:
218
+ ydist = y1 * (y2/y1).abs ** (1/(nb + 1.0))
219
+
220
+ cur_dist = NaturalDistance.new(ydist)
221
+
222
+ retval = []
223
+
224
+ cur_y = y1
225
+ # This flag is necessary to avoid infinite loops
226
+ last_was_decrease = false
227
+
228
+ distance_unchanged = 0
229
+ last_real_distance = false
230
+ while cur_y < y2
231
+ candidates = cur_dist.to_next_decade(cur_y)
232
+ # We now evaluate the distance in real
233
+ real_distance = (from.call(cur_y) - from.call(candidates.last)).abs/
234
+ candidates.size
235
+ if last_real_distance && (real_distance == last_real_distance)
236
+ distance_unchanged += 1
237
+ else
238
+ distance_unchanged = 0
239
+ end
240
+ # p [:cur_y=, cur_y, :y2=, y2, :real_distance, real_distance,
241
+ # :distance=, cur_dist, :xdist_min, xdist_min,
242
+ # :candidates=, *candidates]
243
+
244
+ if (real_distance > 1.25 * xdist_min) &&
245
+ (distance_unchanged < 3)
246
+ cur_dist.decrease
247
+ last_was_decrease = true
248
+ elsif real_distance < 0.75 * xdist_min &&
249
+ !last_was_decrease && (distance_unchanged < 3) &&
250
+ candidates.last <= 10 * y2
251
+ cur_dist.increase
252
+ last_was_decrease = false
253
+ else
254
+ retval += candidates
255
+ cur_y = candidates.last
256
+ last_was_decrease = false
257
+ end
258
+ last_real_distance = real_distance
259
+ end
260
+
261
+ # We need to select them so
262
+ return retval.select do |y|
263
+ y >= y1 and y <= y2
264
+ end
265
+
266
+ end
267
+
268
+
269
+ end
270
+
271
+ end