ctioga2 0.11 → 0.12
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.
- checksums.yaml +4 -4
- data/Changelog +17 -0
- data/lib/ctioga2/commands/commands.rb +2 -1
- data/lib/ctioga2/commands/doc/documentation-commands.rb +2 -1
- data/lib/ctioga2/commands/doc/html.rb +27 -0
- data/lib/ctioga2/commands/general-commands.rb +13 -0
- data/lib/ctioga2/commands/type.rb +1 -1
- data/lib/ctioga2/data/dataset.rb +210 -0
- data/lib/ctioga2/data/stack.rb +1 -1
- data/lib/ctioga2/graphics/elements/primitive.rb +8 -6
- data/lib/ctioga2/graphics/elements/subplot.rb +0 -7
- data/lib/ctioga2/graphics/elements/tangent.rb +3 -1
- data/lib/ctioga2/graphics/elements/xyz-map.rb +47 -28
- data/lib/ctioga2/graphics/styles.rb +1 -0
- data/lib/ctioga2/graphics/styles/arrows.rb +141 -1
- data/lib/ctioga2/graphics/styles/axes.rb +18 -1
- data/lib/ctioga2/graphics/styles/base.rb +41 -2
- data/lib/ctioga2/graphics/styles/box.rb +1 -1
- data/lib/ctioga2/graphics/styles/drawable.rb +60 -54
- data/lib/ctioga2/graphics/styles/errorbar.rb +10 -3
- data/lib/ctioga2/graphics/styles/factory.rb +80 -9
- data/lib/ctioga2/graphics/styles/plot.rb +1 -1
- data/lib/ctioga2/graphics/styles/scope.rb +72 -0
- data/lib/ctioga2/graphics/styles/sets.rb +2 -1
- data/lib/ctioga2/graphics/types.rb +1 -1
- data/lib/ctioga2/graphics/types/dimensions.rb +48 -0
- data/lib/ctioga2/log.rb +12 -0
- data/lib/ctioga2/metabuilder/type.rb +32 -20
- data/lib/ctioga2/metabuilder/types/strings.rb +2 -2
- data/lib/ctioga2/plotmaker.rb +14 -0
- data/lib/ctioga2/utils.rb +51 -3
- data/lib/ctioga2/version.rb +2 -2
- metadata +5 -3
@@ -40,6 +40,9 @@ module CTioga2
|
|
40
40
|
# parameter. It is a hash.
|
41
41
|
attr_accessor :sets
|
42
42
|
|
43
|
+
# The name of the default set, when it isn't 'default'
|
44
|
+
attr_accessor :default_set
|
45
|
+
|
43
46
|
# The description of the parameter.
|
44
47
|
attr_accessor :description
|
45
48
|
|
@@ -60,8 +63,16 @@ module CTioga2
|
|
60
63
|
def initialize(name, type, sets, description,
|
61
64
|
short_option = nil, disable_cmds = false)
|
62
65
|
@name = name
|
63
|
-
@type = type
|
64
|
-
|
66
|
+
@type = type
|
67
|
+
if sets
|
68
|
+
# If the sets is an array, it is of the form [sets, 'default set']
|
69
|
+
if sets.is_a? Array
|
70
|
+
@sets = sets[0]
|
71
|
+
@default_set = sets[1]
|
72
|
+
else
|
73
|
+
@sets = sets
|
74
|
+
end
|
75
|
+
end
|
65
76
|
@description = description
|
66
77
|
@short_option = short_option
|
67
78
|
@disable_commands = disable_cmds
|
@@ -81,7 +92,9 @@ module CTioga2
|
|
81
92
|
# Returns a suitable default set for the given object.
|
82
93
|
def default_set
|
83
94
|
return nil unless @sets
|
84
|
-
if @
|
95
|
+
if @default_set
|
96
|
+
return @sets[@default_set]
|
97
|
+
elsif @sets.key? 'default'
|
85
98
|
return @sets['default']
|
86
99
|
else
|
87
100
|
@sets.each do |k,v|
|
@@ -249,22 +262,36 @@ module CTioga2
|
|
249
262
|
}
|
250
263
|
@parameters_carrays = {}
|
251
264
|
for target, param in self.class.parameters
|
265
|
+
# There should be a way to do that !
|
252
266
|
set = param.default_set
|
253
267
|
if set
|
254
268
|
@parameters_carrays[target] = CircularArray.new(set)
|
255
269
|
end
|
256
270
|
end
|
271
|
+
|
272
|
+
@next_style = nil
|
273
|
+
end
|
274
|
+
|
275
|
+
# Sets the style to be returned from the next call to #next
|
276
|
+
# (not counting the effect of the options passed)
|
277
|
+
def set_next_style(stl)
|
278
|
+
@next_style = stl
|
257
279
|
end
|
258
280
|
|
259
281
|
# Gets the style for the next curve. The _one_time_ hash
|
260
282
|
# contains values 'parameter name' (name, and not target) =>
|
261
283
|
# value that are used for this time only.
|
262
284
|
def next(one_time = {})
|
263
|
-
|
264
|
-
|
265
|
-
|
285
|
+
if @next_style
|
286
|
+
base = @next_style
|
287
|
+
@next_style = nil
|
288
|
+
else
|
289
|
+
base = {}
|
290
|
+
for target, array in @parameters_carrays
|
291
|
+
base[target] = array.next
|
292
|
+
end
|
293
|
+
base.merge!(@override_parameters)
|
266
294
|
end
|
267
|
-
base.merge!(@override_parameters)
|
268
295
|
base.merge!(hash_name_to_target(one_time))
|
269
296
|
return CurveStyle.from_hash(resolve_links(base))
|
270
297
|
end
|
@@ -327,18 +354,29 @@ module CTioga2
|
|
327
354
|
simple_parameter 'line_style', 'line style', Sets::LineStyleSets
|
328
355
|
|
329
356
|
# Markers
|
330
|
-
simple_parameter
|
357
|
+
simple_parameter 'marker', 'marker', Sets::MarkerSets, '-m'
|
331
358
|
|
332
359
|
simple_parameter 'marker_color', "marker color", Sets::ColorSets
|
333
360
|
|
361
|
+
simple_parameter 'marker_fill_color', "marker fill color", [Sets::ColorSets, 'nil']
|
362
|
+
|
363
|
+
simple_parameter 'marker_line_color', "marker stroke color", [Sets::ColorSets, 'nil']
|
364
|
+
|
334
365
|
simple_parameter 'marker_scale', "marker scale", Sets::LineWidthSets
|
335
366
|
|
367
|
+
simple_parameter 'marker_angle', "marker angle", nil
|
368
|
+
|
369
|
+
simple_parameter 'marker_line_width', "marker line width", nil
|
370
|
+
|
336
371
|
simple_parameter 'marker_min_scale', "marker scale", nil
|
337
372
|
|
338
373
|
# Error bars:
|
339
374
|
simple_parameter 'error_bar_color', "error bar color",
|
340
375
|
Sets::ColorSets
|
341
376
|
|
377
|
+
simple_parameter 'error_bar_line_width', "error bar line width",
|
378
|
+
Sets::LineWidthSets
|
379
|
+
|
342
380
|
# Location:
|
343
381
|
define_parameter 'location_xaxis', 'xaxis',
|
344
382
|
nil, "X axis", nil, true
|
@@ -470,7 +508,40 @@ module CTioga2
|
|
470
508
|
return tv
|
471
509
|
end
|
472
510
|
end
|
473
|
-
|
511
|
+
|
512
|
+
SkipCommand =
|
513
|
+
Cmd.new("skip",nil,"--skip",
|
514
|
+
[], {'number' => CmdArg.new("integer")}
|
515
|
+
) do |plotmaker, opts|
|
516
|
+
number = opts['number'] || 1
|
517
|
+
fct = plotmaker.curve_generator.style_factory
|
518
|
+
while number > 0
|
519
|
+
number -= 1
|
520
|
+
fct.next
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
SkipCommand.describe('Skips next curve style',
|
525
|
+
<<EOH, CurveStyleFactory::CurveStyleGroup)
|
526
|
+
This command acts as if one (or @number@) dataset had been drawn with
|
527
|
+
respect to the style of the next dataset to be drawn.
|
528
|
+
EOH
|
529
|
+
|
530
|
+
ReuseCommand =
|
531
|
+
Cmd.new("reuse-style",nil,"--reuse-style",
|
532
|
+
[CmdArg.new('object')], {}
|
533
|
+
) do |plotmaker, obj, opts|
|
534
|
+
stl = obj.curve_style.to_hash
|
535
|
+
plotmaker.curve_generator.style_factory.set_next_style(stl)
|
536
|
+
end
|
537
|
+
|
538
|
+
ReuseCommand.describe('Reuse the style of a previous curve',
|
539
|
+
<<EOH, CurveStyleFactory::CurveStyleGroup)
|
540
|
+
After using this command, the next curve will have the same style as the
|
541
|
+
curve whose name was given as the first argument (it is the name given to
|
542
|
+
the `/id=` option to plot.
|
543
|
+
EOH
|
544
|
+
end
|
474
545
|
|
475
546
|
# Now, we document some aspects of the above created commands
|
476
547
|
c = Commands::Command
|
@@ -439,7 +439,7 @@ EOH
|
|
439
439
|
style = AxisStyle.current_axis_style(plotmaker, w)
|
440
440
|
style.set_from_hash(opts)
|
441
441
|
rescue Exception => e
|
442
|
-
error {"Error while setting style of axis: #{w} -- #{e}"}
|
442
|
+
Log::error {"Error while setting style of axis: #{w} -- #{e}"}
|
443
443
|
end
|
444
444
|
end
|
445
445
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# scope.rb: containers that provide translation and scaling capacities
|
2
|
+
# copyright (c) 2015 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
|
+
module Graphics
|
21
|
+
|
22
|
+
# All the styles
|
23
|
+
module Styles
|
24
|
+
|
25
|
+
# This style represents a scope, ie something that translates
|
26
|
+
# (first) and scales (second) figure coordinates.
|
27
|
+
class ScopeStyle < BasicStyle
|
28
|
+
|
29
|
+
typed_attribute 'xshift', 'dimension'
|
30
|
+
typed_attribute 'xscale', 'float'
|
31
|
+
|
32
|
+
typed_attribute 'yshift', 'dimension'
|
33
|
+
typed_attribute 'yscale', 'float'
|
34
|
+
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
end
|
38
|
+
|
39
|
+
# applies the transformation to the current figure coordinates
|
40
|
+
def apply_to_figure(t)
|
41
|
+
bl = t.bounds_left
|
42
|
+
br = t.bounds_right
|
43
|
+
bt = t.bounds_top
|
44
|
+
bb = t.bounds_bottom
|
45
|
+
|
46
|
+
if @xshift
|
47
|
+
dx = @xshift.to_figure(t,:x)
|
48
|
+
bl -= dx
|
49
|
+
br -= dx
|
50
|
+
end
|
51
|
+
|
52
|
+
if @yshift
|
53
|
+
dy = @yshift.to_figure(t,:y)
|
54
|
+
bt -= dy
|
55
|
+
bb -= dy
|
56
|
+
end
|
57
|
+
|
58
|
+
if @xscale
|
59
|
+
bl, br = *Utils::scale_segment(bl, br, 1/@xscale)
|
60
|
+
end
|
61
|
+
if @yscale
|
62
|
+
bt, bb = *Utils::scale_segment(bt, bb, 1/@yscale)
|
63
|
+
end
|
64
|
+
|
65
|
+
t.set_bounds([bl, br, bt, bb])
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
@@ -51,10 +51,58 @@ module CTioga2
|
|
51
51
|
# _value_ oriented along the given _orientation_
|
52
52
|
def initialize(type, value, orientation = :x)
|
53
53
|
@type = type
|
54
|
+
if not @type.is_a? Symbol
|
55
|
+
raise "Invalid value for the dimension type: '#{@type}'"
|
56
|
+
end
|
54
57
|
@value = value
|
55
58
|
@orientation = orientation
|
56
59
|
end
|
57
60
|
|
61
|
+
def self.make_dimension(val, orient = :x, default = :figure)
|
62
|
+
if val.is_a? Dimension
|
63
|
+
return val
|
64
|
+
else
|
65
|
+
return Dimension.new(default, val, orient)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Gets the angle along the given direction
|
70
|
+
def self.get_angle(t, dx, dy)
|
71
|
+
dx = make_dimension(dx, :x).to_bp(t)
|
72
|
+
dy = make_dimension(dy, :y).to_bp(t)
|
73
|
+
return 180 * Math::atan2(dy, dx)/Math::PI
|
74
|
+
end
|
75
|
+
|
76
|
+
def -@
|
77
|
+
return Dimension.new(@type, -@value, @orientation)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns a dimension corresponding to the distance.
|
81
|
+
def self.get_distance(t, dx, dy)
|
82
|
+
dx = make_dimension(dx, :x).to_bp(t)
|
83
|
+
dy = make_dimension(dy, :y).to_bp(t)
|
84
|
+
return Dimension.new(:bp, (dx**2 + dy**2)**0.5)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Adjusts the given line by adding the dimensions on the left
|
88
|
+
# and on the right (can be negative).
|
89
|
+
#
|
90
|
+
# Returns the new [x1, y1, x2, y2]
|
91
|
+
def self.adjust_line(t, x1, y1, x2, y2, left, right)
|
92
|
+
dx = x2 - x1
|
93
|
+
dy = y2 - y1
|
94
|
+
dst = get_distance(t, x2-x1, y2-y1).to_bp(t)
|
95
|
+
lf = left.to_bp(t)/dst
|
96
|
+
rf = right.to_bp(t)/dst
|
97
|
+
|
98
|
+
x1 -= lf * dx
|
99
|
+
y1 -= lf * dy
|
100
|
+
x2 += rf * dx
|
101
|
+
y2 += rf * dy
|
102
|
+
return [x1, y1, x2, y2]
|
103
|
+
end
|
104
|
+
|
105
|
+
|
58
106
|
# Converts the Dimension to the *figure* coordinates of the
|
59
107
|
# *current* figure in _t_.
|
60
108
|
#
|
data/lib/ctioga2/log.rb
CHANGED
@@ -35,26 +35,31 @@ module CTioga2
|
|
35
35
|
# is not implemented yet.
|
36
36
|
def debug(channel = nil)
|
37
37
|
@@logger.debug {yield + Log.context}
|
38
|
+
@@counts[:debug] += 1
|
38
39
|
end
|
39
40
|
|
40
41
|
# Prints a warning message
|
41
42
|
def warn
|
42
43
|
@@logger.warn {yield + Log.context}
|
44
|
+
@@counts[:warn] += 1
|
43
45
|
end
|
44
46
|
|
45
47
|
# Prints an informational message
|
46
48
|
def info
|
47
49
|
@@logger.info {yield + Log.context}
|
50
|
+
@@counts[:info] += 1
|
48
51
|
end
|
49
52
|
|
50
53
|
# Prints an error message
|
51
54
|
def error
|
52
55
|
@@logger.error {yield + Log.context}
|
56
|
+
@@counts[:error] += 1
|
53
57
|
end
|
54
58
|
|
55
59
|
# Prints a fatal error message and initiates program termination.
|
56
60
|
def fatal
|
57
61
|
@@logger.fatal {yield + Log.context}
|
62
|
+
@@counts[:fatal] += 1 # Though not very useful
|
58
63
|
exit 1 # Fatal error.
|
59
64
|
end
|
60
65
|
|
@@ -70,8 +75,15 @@ module CTioga2
|
|
70
75
|
Logger::Formatter::Format.replace("[%4$s] %6$s\n")
|
71
76
|
@@logger = Logger.new(stream)
|
72
77
|
@@logger.level = Logger::WARN # Warnings and more only by default
|
78
|
+
@@counts = {}
|
79
|
+
for k in [:error, :debug, :warn, :info, :fatal]
|
80
|
+
@@counts[k] = 0
|
81
|
+
end
|
73
82
|
end
|
74
83
|
|
84
|
+
def self.counts
|
85
|
+
return @@counts
|
86
|
+
end
|
75
87
|
|
76
88
|
# Logs to the target file, and fall back onto stderr should
|
77
89
|
# opening fail.
|
@@ -87,6 +87,8 @@ module CTioga2
|
|
87
87
|
# to a Type child
|
88
88
|
@@types = { }
|
89
89
|
|
90
|
+
@@type_names = {}
|
91
|
+
|
90
92
|
# The initial type specification that was given to the Type
|
91
93
|
attr_accessor :type
|
92
94
|
|
@@ -144,6 +146,7 @@ module CTioga2
|
|
144
146
|
"from #{@@types[name]} to #{self}" }
|
145
147
|
end
|
146
148
|
@@types[name] = self
|
149
|
+
@@type_names[self] = name
|
147
150
|
self.send(:define_method,:type_name) do
|
148
151
|
public_name
|
149
152
|
end
|
@@ -190,31 +193,40 @@ module CTioga2
|
|
190
193
|
# function that can take advantage of a few general features. It
|
191
194
|
# is recommanded to define a #string_to_type_internal function
|
192
195
|
# rather to redefine #string_to_type
|
193
|
-
def string_to_type(string)
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
196
|
+
def string_to_type(string, tn = nil)
|
197
|
+
begin
|
198
|
+
# First, passthrough
|
199
|
+
if @passthrough && @passthrough === string
|
200
|
+
return stt_run_hook(string)
|
201
|
+
end
|
202
|
+
# First, shortcuts:
|
203
|
+
if @shortcuts and @shortcuts.key? string
|
204
|
+
return stt_run_hook(@shortcuts[string])
|
205
|
+
end
|
206
|
+
if @re_shortcuts
|
207
|
+
for k, v in @re_shortcuts
|
208
|
+
if string =~ k
|
209
|
+
return stt_run_hook(v)
|
210
|
+
end
|
206
211
|
end
|
207
212
|
end
|
208
|
-
end
|
209
213
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
214
|
+
# Then, constants lookup.
|
215
|
+
if @type.key?(:namespace)
|
216
|
+
begin
|
217
|
+
return stt_run_hook(lookup_const(string))
|
218
|
+
rescue IncorrectInput
|
219
|
+
end
|
215
220
|
end
|
221
|
+
return stt_run_hook(string_to_type_internal(string))
|
222
|
+
rescue Exception => e
|
223
|
+
txt = if tn
|
224
|
+
"to type '#{tn}' failed:\n\t -> "
|
225
|
+
else
|
226
|
+
"failed: "
|
227
|
+
end
|
228
|
+
raise "Conversion of '#{string}' #{txt}#{e.message}"
|
216
229
|
end
|
217
|
-
return stt_run_hook(string_to_type_internal(string))
|
218
230
|
end
|
219
231
|
|
220
232
|
# This function does the exact opposite of the #string_to_type
|
@@ -34,7 +34,7 @@ module CTioga2
|
|
34
34
|
return 'text'
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
37
|
+
def string_to_type_internal(str)
|
38
38
|
return str
|
39
39
|
end
|
40
40
|
end
|
@@ -67,7 +67,7 @@ module CTioga2
|
|
67
67
|
return 'regexp'
|
68
68
|
end
|
69
69
|
|
70
|
-
def
|
70
|
+
def string_to_type_internal(str)
|
71
71
|
if str =~ /^\/(.*)\/$/
|
72
72
|
return Regexp.new($1)
|
73
73
|
else
|