ctioga2 0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +339 -0
- data/Changelog +6 -0
- data/bin/ctioga2 +26 -0
- data/lib/ctioga2/commands/arguments.rb +58 -0
- data/lib/ctioga2/commands/commands.rb +258 -0
- data/lib/ctioga2/commands/doc/doc.rb +118 -0
- data/lib/ctioga2/commands/doc/documentation-commands.rb +119 -0
- data/lib/ctioga2/commands/doc/help.rb +95 -0
- data/lib/ctioga2/commands/doc/html.rb +230 -0
- data/lib/ctioga2/commands/doc/introspection.rb +211 -0
- data/lib/ctioga2/commands/doc/man.rb +279 -0
- data/lib/ctioga2/commands/doc/markup.rb +359 -0
- data/lib/ctioga2/commands/general-commands.rb +119 -0
- data/lib/ctioga2/commands/general-types.rb +118 -0
- data/lib/ctioga2/commands/groups.rb +73 -0
- data/lib/ctioga2/commands/interpreter.rb +257 -0
- data/lib/ctioga2/commands/parsers/command-line.rb +187 -0
- data/lib/ctioga2/commands/parsers/file.rb +186 -0
- data/lib/ctioga2/commands/strings.rb +303 -0
- data/lib/ctioga2/commands/type.rb +100 -0
- data/lib/ctioga2/commands/variables.rb +101 -0
- data/lib/ctioga2/data/backends/backend.rb +260 -0
- data/lib/ctioga2/data/backends/backends.rb +39 -0
- data/lib/ctioga2/data/backends/backends/gnuplot.rb +140 -0
- data/lib/ctioga2/data/backends/backends/math.rb +121 -0
- data/lib/ctioga2/data/backends/backends/text.rb +335 -0
- data/lib/ctioga2/data/backends/description.rb +405 -0
- data/lib/ctioga2/data/backends/factory.rb +73 -0
- data/lib/ctioga2/data/backends/parameter.rb +109 -0
- data/lib/ctioga2/data/datacolumn.rb +245 -0
- data/lib/ctioga2/data/dataset.rb +233 -0
- data/lib/ctioga2/data/filters.rb +131 -0
- data/lib/ctioga2/data/merge.rb +43 -0
- data/lib/ctioga2/data/point.rb +72 -0
- data/lib/ctioga2/data/stack.rb +294 -0
- data/lib/ctioga2/graphics/coordinates.rb +73 -0
- data/lib/ctioga2/graphics/elements.rb +111 -0
- data/lib/ctioga2/graphics/elements/containers.rb +111 -0
- data/lib/ctioga2/graphics/elements/curve2d.rb +155 -0
- data/lib/ctioga2/graphics/elements/element.rb +90 -0
- data/lib/ctioga2/graphics/elements/primitive.rb +256 -0
- data/lib/ctioga2/graphics/elements/subplot.rb +140 -0
- data/lib/ctioga2/graphics/generator.rb +68 -0
- data/lib/ctioga2/graphics/legends.rb +108 -0
- data/lib/ctioga2/graphics/legends/area.rb +199 -0
- data/lib/ctioga2/graphics/legends/items.rb +183 -0
- data/lib/ctioga2/graphics/legends/provider.rb +58 -0
- data/lib/ctioga2/graphics/legends/storage.rb +65 -0
- data/lib/ctioga2/graphics/root.rb +209 -0
- data/lib/ctioga2/graphics/styles.rb +30 -0
- data/lib/ctioga2/graphics/styles/axes.rb +247 -0
- data/lib/ctioga2/graphics/styles/background.rb +122 -0
- data/lib/ctioga2/graphics/styles/base.rb +115 -0
- data/lib/ctioga2/graphics/styles/carrays.rb +53 -0
- data/lib/ctioga2/graphics/styles/curve.rb +101 -0
- data/lib/ctioga2/graphics/styles/drawable.rb +87 -0
- data/lib/ctioga2/graphics/styles/factory.rb +351 -0
- data/lib/ctioga2/graphics/styles/legend.rb +63 -0
- data/lib/ctioga2/graphics/styles/plot.rb +410 -0
- data/lib/ctioga2/graphics/styles/sets.rb +64 -0
- data/lib/ctioga2/graphics/styles/texts.rb +277 -0
- data/lib/ctioga2/graphics/subplot-commands.rb +141 -0
- data/lib/ctioga2/graphics/types.rb +188 -0
- data/lib/ctioga2/graphics/types/bijection.rb +79 -0
- data/lib/ctioga2/graphics/types/boundaries.rb +170 -0
- data/lib/ctioga2/graphics/types/boxes.rb +157 -0
- data/lib/ctioga2/graphics/types/dimensions.rb +157 -0
- data/lib/ctioga2/graphics/types/point.rb +247 -0
- data/lib/ctioga2/log.rb +97 -0
- data/lib/ctioga2/metabuilder/type.rb +316 -0
- data/lib/ctioga2/metabuilder/types.rb +39 -0
- data/lib/ctioga2/metabuilder/types/coordinates.rb +124 -0
- data/lib/ctioga2/metabuilder/types/dates.rb +43 -0
- data/lib/ctioga2/metabuilder/types/lists.rb +188 -0
- data/lib/ctioga2/metabuilder/types/numbers.rb +97 -0
- data/lib/ctioga2/metabuilder/types/strings.rb +93 -0
- data/lib/ctioga2/metabuilder/types/styles.rb +178 -0
- data/lib/ctioga2/plotmaker.rb +677 -0
- data/lib/ctioga2/postprocess.rb +115 -0
- data/lib/ctioga2/utils.rb +120 -0
- data/setup.rb +1586 -0
- metadata +144 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
# backends.rb: all the backends
|
2
|
+
|
3
|
+
# This program is free software; you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation; either version 2 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful, but
|
9
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
11
|
+
# General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program; if not, write to the Free Software
|
15
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
16
|
+
# USA
|
17
|
+
|
18
|
+
|
19
|
+
require 'ctioga2/data/backends/backend'
|
20
|
+
|
21
|
+
# We try to look for all files under a ctioga2/metabuilder/types
|
22
|
+
# directory anywhere on the $: path
|
23
|
+
|
24
|
+
files = []
|
25
|
+
for dir in $:
|
26
|
+
Dir[dir + '/ctioga2/data/backends/backends/**/*'].each do |f|
|
27
|
+
f =~ /ctioga2\/data\/backends\/backends\/(.*)\.[^.]+$/
|
28
|
+
files << $1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
for file in files.uniq
|
33
|
+
begin
|
34
|
+
require "ctioga2/data/backends/backends/#{file}"
|
35
|
+
rescue Exception => e
|
36
|
+
warn "There was a problem trying to load 'ctioga2/data/backends/backends/#{file}': "
|
37
|
+
warn "#{e.inspect}"
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# gnuplot.rb: a backend to extract plots from gnuplot's files
|
2
|
+
# Copyright (C) 2007,2009 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.
|
13
|
+
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
require 'Dobjects/Dvector'
|
21
|
+
require 'Dobjects/Function'
|
22
|
+
|
23
|
+
# To feed data to fancyread
|
24
|
+
require 'stringio'
|
25
|
+
|
26
|
+
module CTioga2
|
27
|
+
|
28
|
+
Version::register_svn_info('$Revision: 61 $', '$Date: 2009-05-29 01:00:56 +0200 (Fri, 29 May 2009) $')
|
29
|
+
|
30
|
+
|
31
|
+
module Data
|
32
|
+
|
33
|
+
module Backends
|
34
|
+
|
35
|
+
class GnuplotBackend < Backend
|
36
|
+
|
37
|
+
include Dobjects
|
38
|
+
include Log
|
39
|
+
|
40
|
+
describe 'gnuplot', 'Gnuplot files', <<EOD
|
41
|
+
This backend hijacks gnuplot files to make extract data which they plot.
|
42
|
+
No information is taken about the style !
|
43
|
+
EOD
|
44
|
+
|
45
|
+
param_accessor :variables_overrides, 'vars',
|
46
|
+
"Variable overrides", 'text', <<EOD
|
47
|
+
A colon-separated override of local variables, such as a=1;b=3;c=5
|
48
|
+
EOD
|
49
|
+
|
50
|
+
param_accessor :range, 'range',
|
51
|
+
"Plotting X range", 'float-range',
|
52
|
+
"The plotting X range, such as 0:2"
|
53
|
+
|
54
|
+
# This is called by the architecture to get the data. It splits
|
55
|
+
# the set name into filename@cols, reads the file if necessary and
|
56
|
+
# calls get_data
|
57
|
+
def query_dataset(set)
|
58
|
+
set =~ /^(.*?)(?:@(\d+))?(?::(.*))?$/
|
59
|
+
filename = $1
|
60
|
+
if $2
|
61
|
+
number = $2.to_i - 1
|
62
|
+
else
|
63
|
+
number = 0
|
64
|
+
end
|
65
|
+
if $3
|
66
|
+
overrides = "#{@variable_overrides};#{$3}"
|
67
|
+
else
|
68
|
+
overrides = @variable_overrides
|
69
|
+
end
|
70
|
+
plots = run_gnuplot(filename, overrides)
|
71
|
+
return Dataset.new(set,plots[number])
|
72
|
+
end
|
73
|
+
|
74
|
+
# Runs gnuplot on the file, and returns all datasets found
|
75
|
+
# inside it.
|
76
|
+
def run_gnuplot(filename, overrides = @variables_overrides)
|
77
|
+
date = File::mtime(filename)
|
78
|
+
# Get it from the cache !
|
79
|
+
debug "Running gnuplot on file #{filename}"
|
80
|
+
f = File.open(filename)
|
81
|
+
# We open a bidirectionnal connection to gnuplot:
|
82
|
+
gnuplot = IO.popen("gnuplot", "r+")
|
83
|
+
output = ""
|
84
|
+
gnuplot.puts "set term table"
|
85
|
+
for line in f
|
86
|
+
next if line =~ /set\s+term/
|
87
|
+
if overrides and line =~ /plot\s+/
|
88
|
+
debug "Found a plot, inserting variable overrides: #{overrides}"
|
89
|
+
line.gsub!(/plot\s+/, "#{overrides};plot ")
|
90
|
+
end
|
91
|
+
if @range and line =~ /plot\s+/
|
92
|
+
debug "Found a plot, inserting range: #{@range}"
|
93
|
+
line.gsub!(/plot\s+(\[[^\]]+\])?/,
|
94
|
+
"plot [#{@range}]")
|
95
|
+
end
|
96
|
+
gnuplot.print line
|
97
|
+
gnuplot.flush
|
98
|
+
output += slurp(gnuplot)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Output a "\n" in the end.
|
102
|
+
|
103
|
+
gnuplot.puts ""
|
104
|
+
gnuplot.flush
|
105
|
+
gnuplot.close_write
|
106
|
+
# Then we get all that is remaining:
|
107
|
+
output += gnuplot.read
|
108
|
+
gnuplot.close
|
109
|
+
|
110
|
+
# Now, interaction with gnuplot is finished, and we want to
|
111
|
+
# parse that:
|
112
|
+
outputs = output.split("\n\n")
|
113
|
+
plots = []
|
114
|
+
for data in outputs
|
115
|
+
plots << Dvector.fancy_read(StringIO.new(data), [0,1])
|
116
|
+
end
|
117
|
+
# This block evaluates to plots:
|
118
|
+
return plots
|
119
|
+
end
|
120
|
+
|
121
|
+
# Gets all data from the given file until it blocks, and returns it.
|
122
|
+
def slurp(f, size = 10240)
|
123
|
+
str = ""
|
124
|
+
begin
|
125
|
+
while IO::select([f],[],[],0)
|
126
|
+
ret = f.readpartial(size)
|
127
|
+
if ret.empty?
|
128
|
+
return str
|
129
|
+
end
|
130
|
+
str << ret
|
131
|
+
end
|
132
|
+
end
|
133
|
+
return str
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# math.rb :the Math backend: data based on mathematical formulas.
|
2
|
+
# Copyright (C) 2006 - 2009 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.
|
13
|
+
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
17
|
+
|
18
|
+
|
19
|
+
require 'Dobjects/Dvector'
|
20
|
+
require 'Dobjects/Function'
|
21
|
+
|
22
|
+
module CTioga2
|
23
|
+
|
24
|
+
Version::register_svn_info('$Revision: 17 $', '$Date: 2009-04-28 22:22:22 +0200 (Tue, 28 Apr 2009) $')
|
25
|
+
|
26
|
+
module Data
|
27
|
+
|
28
|
+
module Backends
|
29
|
+
|
30
|
+
class MathBackend < Backend
|
31
|
+
|
32
|
+
include Dobjects
|
33
|
+
include Math
|
34
|
+
|
35
|
+
describe 'math', 'Mathematical functions', <<EOD
|
36
|
+
This backend returns computations of mathematical formulas.
|
37
|
+
EOD
|
38
|
+
|
39
|
+
# TODO: make provisions for 3-D datasets. Ideas: x(t):y(t):z(t)
|
40
|
+
# for parametric plots ? (possibly x(t):y1(t):y2(t):...:yn(t)) ?
|
41
|
+
|
42
|
+
param_accessor :samples, 'samples', "Samples", 'integer',
|
43
|
+
"The number of points"
|
44
|
+
param_accessor :x_range, 'xrange', "X Range", 'float-range',
|
45
|
+
"X range (a:b)"
|
46
|
+
param_accessor :t_range, 'trange', "T Range", 'float-range',
|
47
|
+
"T range (a:b) (parametric plot)"
|
48
|
+
|
49
|
+
param_accessor :log, 'log', "Logarithmic scale", 'boolean',
|
50
|
+
"Space samples logarithmically"
|
51
|
+
|
52
|
+
def initialize
|
53
|
+
super()
|
54
|
+
@samples = 100
|
55
|
+
@x_range = -10.0..10.0
|
56
|
+
@t_range = -10.0..10.0
|
57
|
+
@log = false
|
58
|
+
end
|
59
|
+
|
60
|
+
# This is called by the architecture to get the data. It first
|
61
|
+
# splits the set name into func@range.
|
62
|
+
def query_dataset(set)
|
63
|
+
if set =~ /(.*)@(.*)/
|
64
|
+
set = $1
|
65
|
+
range = $2
|
66
|
+
end
|
67
|
+
name = "math: #{set}"
|
68
|
+
if set =~ /:/ # parametric
|
69
|
+
if range
|
70
|
+
set_param_from_string(:t_range, range)
|
71
|
+
end
|
72
|
+
varname = "t"
|
73
|
+
values = make_dvector(@t_range, @samples, @log)
|
74
|
+
else
|
75
|
+
if range
|
76
|
+
set_param_from_string(:x_range, range)
|
77
|
+
end
|
78
|
+
varname = "x"
|
79
|
+
values = make_dvector(@x_range, @samples, @log)
|
80
|
+
set = "x:#{set}"
|
81
|
+
end
|
82
|
+
return Dataset.dataset_from_spec(name, set) do |b|
|
83
|
+
get_data_column(b, varname, values)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
protected
|
89
|
+
|
90
|
+
# Turns a Range and a number of points into a Dvector
|
91
|
+
def make_dvector(range, nb_points, log = @log)
|
92
|
+
n = nb_points -1
|
93
|
+
a = Dvector.new(nb_points) { |i|
|
94
|
+
i.to_f/(n.to_f)
|
95
|
+
}
|
96
|
+
# a is in [0:1] inclusive...
|
97
|
+
if log
|
98
|
+
delta = range.last/range.first
|
99
|
+
# delta is positive necessarily
|
100
|
+
a *= delta.log
|
101
|
+
a.exp!
|
102
|
+
a *= range.first
|
103
|
+
else
|
104
|
+
delta = range.last - range.first
|
105
|
+
a *= delta
|
106
|
+
a += range.first
|
107
|
+
end
|
108
|
+
return a
|
109
|
+
end
|
110
|
+
|
111
|
+
# Uses compute_formula to get data from
|
112
|
+
def get_data_column(column, variable, values)
|
113
|
+
column.gsub!(/\b#{variable}\b/, "(column[0])")
|
114
|
+
Dvector.compute_formula(column, [values])
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,335 @@
|
|
1
|
+
# text.rb : A simple backend to deal with basic text files.
|
2
|
+
# Copyright (C) 2006 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.
|
13
|
+
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
require 'Dobjects/Dvector'
|
21
|
+
require 'Dobjects/Function'
|
22
|
+
|
23
|
+
# For separated sets
|
24
|
+
require 'stringio'
|
25
|
+
|
26
|
+
module CTioga2
|
27
|
+
|
28
|
+
Version::register_svn_info('$Revision: 17 $', '$Date: 2009-04-28 22:22:22 +0200 (Tue, 28 Apr 2009) $')
|
29
|
+
|
30
|
+
|
31
|
+
module Data
|
32
|
+
|
33
|
+
# A module for easy use of NaN in operations
|
34
|
+
module NaN
|
35
|
+
NaN = 0.0/0.0
|
36
|
+
def nan
|
37
|
+
return NaN
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module Backends
|
42
|
+
|
43
|
+
class TextBackend < Backend
|
44
|
+
|
45
|
+
# A constant holding a relation extension -> command to
|
46
|
+
# decompress (to be fed to sprintf with the filename as argument)
|
47
|
+
UNCOMPRESSORS = {
|
48
|
+
".gz" => "gunzip -c %s",
|
49
|
+
".bz2" => "bunzip2 -c %s",
|
50
|
+
".lzma" => "unlzma -c %s",
|
51
|
+
".lz" => "unlzma -c %s",
|
52
|
+
}
|
53
|
+
|
54
|
+
include Dobjects
|
55
|
+
|
56
|
+
describe 'text', 'Text format', <<EOD
|
57
|
+
This backend can read text files in a format close to the one understood
|
58
|
+
by gnuplot and the like.
|
59
|
+
EOD
|
60
|
+
|
61
|
+
# Inherit the baseline handling, can be useful !
|
62
|
+
# inherit_parameters :base_line
|
63
|
+
|
64
|
+
param_accessor :skip, 'skip', "Skip lines", 'integer',
|
65
|
+
"Number of lines to be skipped at the beginning of the file"
|
66
|
+
|
67
|
+
param_accessor :default_column_spec, 'col',
|
68
|
+
"Default column specification", 'text',
|
69
|
+
"Which columns to use when the @1:2 syntax is not used"
|
70
|
+
|
71
|
+
param_accessor :split, 'split', "Split into subsets", 'boolean',
|
72
|
+
"If true, splits files into subsets on blank/non number lines"
|
73
|
+
|
74
|
+
|
75
|
+
param_accessor :separator, 'separator', "Data columns separator",
|
76
|
+
'regexp',
|
77
|
+
"The columns separator. Defaults to /\s+/"
|
78
|
+
|
79
|
+
|
80
|
+
# param_accessor :select, 'select', "Select lines", {:type => :string},
|
81
|
+
# "Skips line where the code returns false"
|
82
|
+
|
83
|
+
def initialize
|
84
|
+
@dummy = nil
|
85
|
+
@current = nil
|
86
|
+
# Current is the name of the last file used. Necessary for '' specs.
|
87
|
+
@current_data = nil # The data of the last file used.
|
88
|
+
@skip = 0
|
89
|
+
@included_modules = [NaN] # to make sure we give them to
|
90
|
+
# Dvector.compute_formula
|
91
|
+
@default_column_spec = "1:2"
|
92
|
+
|
93
|
+
@separator = /\s+/
|
94
|
+
|
95
|
+
# We don't split data by default.
|
96
|
+
@split = false
|
97
|
+
|
98
|
+
super()
|
99
|
+
|
100
|
+
# Override Backend's cache - for now.
|
101
|
+
@cache = {} # A cache file_name -> data
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
def extend(mod)
|
106
|
+
super
|
107
|
+
@included_modules << mod
|
108
|
+
end
|
109
|
+
|
110
|
+
# Expands specifications into few sets. This function will separate the
|
111
|
+
# set into a file spec and a col spec. Within the col spec, the 2##6
|
112
|
+
# keyword is used to expand to 2,3,4,5,6. 2## followed by a non-digit
|
113
|
+
# expands to 2,...,last column in the file. For now, the expansions
|
114
|
+
# stops on the first occurence found, and the second form doesn't
|
115
|
+
# work yet. But soon...
|
116
|
+
def expand_sets(spec)
|
117
|
+
if m = /(\d+)##(\D|$)/.match(spec)
|
118
|
+
a = m[1].to_i
|
119
|
+
trail = m[2]
|
120
|
+
b = read_file(spec)
|
121
|
+
b = (b.length - 1)
|
122
|
+
ret = []
|
123
|
+
a.upto(b) do |i|
|
124
|
+
ret << m.pre_match + i.to_s + trail + m.post_match
|
125
|
+
end
|
126
|
+
return ret
|
127
|
+
else
|
128
|
+
return super
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
protected
|
134
|
+
|
135
|
+
|
136
|
+
# Returns a IO object suitable to acquire data from it for
|
137
|
+
# the given _file_, which can be one of the following:
|
138
|
+
# * a real file name
|
139
|
+
# * a compressed file name
|
140
|
+
# * a pipe command.
|
141
|
+
def get_io_object(file)
|
142
|
+
if file == "-"
|
143
|
+
return $stdin
|
144
|
+
elsif file =~ /(.*?)\|\s*$/ # A pipe
|
145
|
+
return IO.popen($1)
|
146
|
+
elsif not File.readable?(file)
|
147
|
+
# Try to find a compressed version
|
148
|
+
for ext,method in UNCOMPRESSORS
|
149
|
+
if File.readable? "#{file}#{ext}"
|
150
|
+
info "Using compressed file #{file}#{ext} in stead of #{file}"
|
151
|
+
return IO.popen(method % "#{file}#{ext}")
|
152
|
+
end
|
153
|
+
end
|
154
|
+
else
|
155
|
+
for ext, method in UNCOMPRESSORS
|
156
|
+
if file =~ /#{ext}$/
|
157
|
+
info "Taking file #{file} as a compressed file"
|
158
|
+
return IO.popen(method % file)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
return File::open(file)
|
162
|
+
end
|
163
|
+
error "Could not open #{file}"
|
164
|
+
return nil
|
165
|
+
end
|
166
|
+
|
167
|
+
# A line is invalid if it is blank or starts
|
168
|
+
# neither with a digit nor +, - or .
|
169
|
+
#
|
170
|
+
# Maybe to be improved later.
|
171
|
+
InvalidLineRE = /^\s*$|^\s*[^\d+.\s-]+/
|
172
|
+
|
173
|
+
# Returns a string corresponding to the given _set_ of the
|
174
|
+
# given _io_ object.
|
175
|
+
#
|
176
|
+
# Sets are 1-based.
|
177
|
+
def get_set_string(io, set)
|
178
|
+
cur_set = 1
|
179
|
+
last_line_is_invalid = true
|
180
|
+
str = ""
|
181
|
+
line_number = 0
|
182
|
+
while line = io.gets
|
183
|
+
line_number += 1
|
184
|
+
if line =~ InvalidLineRE
|
185
|
+
debug "Found invalid line at #{line_number}"
|
186
|
+
if ! last_line_is_invalid
|
187
|
+
# We begin a new set.
|
188
|
+
cur_set += 1
|
189
|
+
debug "Found set #{cur_set} at line #{line_number}"
|
190
|
+
if(cur_set > set)
|
191
|
+
return str
|
192
|
+
end
|
193
|
+
end
|
194
|
+
last_line_is_invalid = true
|
195
|
+
else
|
196
|
+
last_line_is_invalid = false
|
197
|
+
if cur_set == set
|
198
|
+
str += line
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
return str
|
203
|
+
end
|
204
|
+
|
205
|
+
# Returns an IO object corresponding to the given file.
|
206
|
+
def get_io_set(file)
|
207
|
+
if not @split
|
208
|
+
return get_io_object(file)
|
209
|
+
else
|
210
|
+
file =~ /(.*?)(?:#(\d+))?$/; # ; to make ruby-mode indent correctly.
|
211
|
+
filename = $1
|
212
|
+
if $2
|
213
|
+
set = $2.to_i
|
214
|
+
else
|
215
|
+
set = 1
|
216
|
+
end
|
217
|
+
debug "Trying to get set #{set} from file '#{filename}'"
|
218
|
+
str = get_set_string(get_io_object(filename), set)
|
219
|
+
return StringIO.new(str)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# Reads data from a file. If needed, extract the file from the
|
224
|
+
# columns specification.
|
225
|
+
#
|
226
|
+
# TODO: the cache really should include things such as time of
|
227
|
+
# last modification and various parameters that influence the
|
228
|
+
# reading of the file.
|
229
|
+
def read_file(file)
|
230
|
+
if file =~ /(.*)@.*/
|
231
|
+
file = $1
|
232
|
+
end
|
233
|
+
name = file # As file will be modified.
|
234
|
+
if ! @cache.key?(file) # Read the file if it is not cached.
|
235
|
+
fancy_read_options = {'index_col' => true,
|
236
|
+
'skip_first' => @skip,
|
237
|
+
'sep' => @separator
|
238
|
+
}
|
239
|
+
io_set = get_io_set(file)
|
240
|
+
debug "Fancy read '#{file}', options #{fancy_read_options.inspect}"
|
241
|
+
@cache[name] = Dvector.fancy_read(io_set, nil, fancy_read_options)
|
242
|
+
end
|
243
|
+
return @cache[name]
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
# This is called by the architecture to get the data. It
|
248
|
+
# splits the set name into filename@cols, reads the file if
|
249
|
+
# necessary and calls get_data
|
250
|
+
def query_dataset(set)
|
251
|
+
if set =~ /(.*)@(.*)/
|
252
|
+
col_spec = $2
|
253
|
+
file = $1
|
254
|
+
else
|
255
|
+
col_spec = @default_column_spec
|
256
|
+
file = set
|
257
|
+
end
|
258
|
+
if file.length > 0
|
259
|
+
@current_data = read_file(file)
|
260
|
+
@current = file
|
261
|
+
end
|
262
|
+
|
263
|
+
# Wether we need or not to compute formulas:
|
264
|
+
if col_spec =~ /\$/
|
265
|
+
compute_formulas = true
|
266
|
+
else
|
267
|
+
compute_formulas = false
|
268
|
+
end
|
269
|
+
|
270
|
+
return Dataset.dataset_from_spec(set, col_spec) do |col|
|
271
|
+
get_data_column(col, compute_formulas)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
# Gets the data corresponding to the given column. If
|
276
|
+
# _compute_formulas_ is true, the column specification is
|
277
|
+
# taken to be a formula (in the spirit of gnuplot's)
|
278
|
+
def get_data_column(column, compute_formulas = false)
|
279
|
+
if compute_formulas
|
280
|
+
formula = column.gsub(/\$(\d+)/, 'column[\1]')
|
281
|
+
debug "Using formula #{formula} for column spec: #{column}"
|
282
|
+
return Dvector.compute_formula(formula,
|
283
|
+
@current_data,
|
284
|
+
@included_modules)
|
285
|
+
else
|
286
|
+
return @current_data[column.to_i].dup
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# # Turns a target => values specification into something usable as
|
291
|
+
# # error bars, that is :xmin, :xmax and the like hashes. The rules
|
292
|
+
# # are the following:
|
293
|
+
# # * ?min/?max are passed on directly;
|
294
|
+
# # * ?e(abs) are transformed into ?min = ? - ?eabs, ?max = ? + ?eabs
|
295
|
+
# # * ?eu(p/?ed(own) are transformed respectively into ? +/- ?...
|
296
|
+
# # * ?er(el) become ?min = ?*(1 - ?erel, ?max = ?(1 + ?erel)
|
297
|
+
# # * ?erup/?erdown follow the same pattern...
|
298
|
+
# def compute_error_bars(values)
|
299
|
+
# target = {}
|
300
|
+
# for key in values.keys
|
301
|
+
# case key.to_s
|
302
|
+
# when /^[xy](min|max)?$/
|
303
|
+
# target[key] = values[key].dup # Just to make sure.
|
304
|
+
# when /^(.)e(a(bs?)?)?$/
|
305
|
+
# target["#{$1}min".to_sym] = values[$1.to_sym] - values[key]
|
306
|
+
# target["#{$1}max".to_sym] = values[$1.to_sym] + values[key]
|
307
|
+
# when /^(.)eu(p)?$/
|
308
|
+
# target["#{$1}max".to_sym] = values[$1.to_sym] + values[key]
|
309
|
+
# when /^(.)ed(o(wn?)?)?$/
|
310
|
+
# target["#{$1}min".to_sym] = values[$1.to_sym] - values[key]
|
311
|
+
# when /^(.)er(el?)?$/
|
312
|
+
# target["#{$1}min".to_sym] = values[$1.to_sym] *
|
313
|
+
# (values[key].neg + 1)
|
314
|
+
# target["#{$1}max".to_sym] = values[$1.to_sym] *
|
315
|
+
# (values[key] + 1)
|
316
|
+
# when /^(.)erd(o(wn?)?)?$/
|
317
|
+
# target["#{$1}min".to_sym] = values[$1.to_sym] *
|
318
|
+
# (values[key].neg + 1)
|
319
|
+
# when /^(.)erup?$/
|
320
|
+
# target["#{$1}max".to_sym] = values[$1.to_sym] *
|
321
|
+
# (values[key] + 1)
|
322
|
+
# else
|
323
|
+
# warn "Somehow, the target specification #{key} " +
|
324
|
+
# "didn't make it through"
|
325
|
+
# end
|
326
|
+
# end
|
327
|
+
# return target
|
328
|
+
# end
|
329
|
+
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
end
|
335
|
+
end
|