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
@@ -19,7 +19,7 @@ require 'ctioga2/commands/strings'
19
19
 
20
20
  module CTioga2
21
21
 
22
- Version::register_svn_info('$Revision: 2 $', '$Date: 2009-04-25 14:03:30 +0200 (Sat, 25 Apr 2009) $')
22
+ Version::register_svn_info('$Revision: 151 $', '$Date: 2010-06-19 23:45:20 +0200 (Sat, 19 Jun 2010) $')
23
23
 
24
24
  module Commands
25
25
 
@@ -96,11 +96,13 @@ module CTioga2
96
96
  # Problem: the space on the right of the = sign is
97
97
  # *significant*.
98
98
  for o in args
99
- if o =~ /^\s*([\w-]+)\s*=(.*)/
99
+ if o =~ /^\s*\/?([\w-]+)\s*=(.*)/
100
100
  if cmd.has_option? $1
101
101
  options[$1] = $2
102
102
  else
103
- error "Command #{cmd.name} does not take option #{$1}"
103
+ error {
104
+ "Command #{cmd.name} does not take option #{$1}"
105
+ }
104
106
  end
105
107
  end
106
108
  end
@@ -16,11 +16,16 @@ require 'ctioga2/metabuilder/types'
16
16
 
17
17
  module CTioga2
18
18
 
19
- Version::register_svn_info('$Revision: 18 $', '$Date: 2009-04-28 23:43:54 +0200 (Tue, 28 Apr 2009) $')
19
+ Version::register_svn_info('$Revision: 173 $', '$Date: 2010-10-22 21:41:39 +0200 (Fri, 22 Oct 2010) $')
20
20
 
21
21
  module Commands
22
22
 
23
23
  # A named type, based on CTioga2::MetaBuilder::Type
24
+ #
25
+ # @todo *Structural* in real, I don't think it is necessary
26
+ # anymore to rely on MetaBuilder, as most types in CTioga2 already
27
+ # provide a from_text class function that does a nice job. I
28
+ # should convert as many things as possible to using that.
24
29
  class CommandType
25
30
 
26
31
  # The underlying CTioga2::MetaBuilder::Type object.
@@ -43,7 +48,9 @@ module CTioga2
43
48
  return obj
44
49
  else
45
50
  if obj.is_a? Symbol
46
- warn "Converting type specifcation #{obj.inspect} to string at #{caller[1]}"
51
+ warn {
52
+ "Converting type specification #{obj.inspect} to string at #{caller[1]}"
53
+ }
47
54
  obj = obj.to_s
48
55
  end
49
56
  type = Interpreter::type(obj)
@@ -87,7 +94,7 @@ module CTioga2
87
94
 
88
95
  # Returns the long option for the option parser.
89
96
  #
90
- # TODO: maybe this should be rethought a bit ?
97
+ # \todo maybe this should be rethought a bit ?
91
98
  def option_parser_long_option(name, param = nil)
92
99
  return @type.option_parser_long_option(name, param)
93
100
  end
@@ -16,7 +16,7 @@ require 'ctioga2/commands/strings'
16
16
 
17
17
  module CTioga2
18
18
 
19
- Version::register_svn_info('$Revision: 2 $', '$Date: 2009-04-25 14:03:30 +0200 (Sat, 25 Apr 2009) $')
19
+ Version::register_svn_info('$Revision: 155 $', '$Date: 2010-06-21 21:41:32 +0200 (Mon, 21 Jun 2010) $')
20
20
 
21
21
  module Commands
22
22
 
@@ -43,7 +43,7 @@ module CTioga2
43
43
  # variable = value
44
44
  # They are stored in the form on an InterpreterString
45
45
  #
46
- # TODO: The variables system should automatically transform
46
+ # \todo The variables system should automatically transform
47
47
  # recursive variables into immediate ones when there is no
48
48
  # variables replacement text.
49
49
  class Variables
@@ -21,7 +21,7 @@ require 'ctioga2/data/backends/description'
21
21
 
22
22
  module CTioga2
23
23
 
24
- Version::register_svn_info('$Revision: 59 $', '$Date: 2009-05-28 23:15:50 +0200 (Thu, 28 May 2009) $')
24
+ Version::register_svn_info('$Revision: 155 $', '$Date: 2010-06-21 21:41:32 +0200 (Mon, 21 Jun 2010) $')
25
25
 
26
26
 
27
27
  module Data
@@ -36,7 +36,7 @@ module CTioga2
36
36
  # to retrive data from some source with a consistent way to do so,
37
37
  # independent the kind of source accessed.
38
38
  #
39
- # TODO: update documentation.
39
+ # \todo update documentation.
40
40
  #
41
41
  # Subclasses should:
42
42
  # * provide a consistent method for creating themselves,
@@ -55,11 +55,11 @@ module CTioga2
55
55
  # * wether the actual reading of the data is done at initialization time
56
56
  # or at query time is left to the implementor ;-) !
57
57
  #
58
- # TODO: adapt to the new structure.
58
+ # \todo adapt to the new structure.
59
59
  #
60
- # TODO: add back filters (with time)
60
+ # \todo add back filters (with time)
61
61
  #
62
- # TODO: add a Cache ?
62
+ # \todo add a Cache ?
63
63
  class Backend
64
64
 
65
65
  # Include logging facilities...
@@ -106,7 +106,7 @@ This is the base class for backends. It should never be used directly.
106
106
  EOD
107
107
 
108
108
 
109
- # TODO: the baseline should not be implemented.
109
+ # \todo the baseline should not be implemented.
110
110
  # It is much more efficient to ;
111
111
  # * implement a dataset subtraction command;
112
112
  # * use the add-dataset hook to automatically subtract a given
@@ -159,7 +159,7 @@ EOD
159
159
  # code while keeping old stuff working.
160
160
  def expand_sets(spec)
161
161
  if m = /(\d+)##(\d+)/.match(spec)
162
- debug "Using expansion rule #1"
162
+ debug { "Using expansion rule #1" }
163
163
  a = m[1].to_i
164
164
  b = m[2].to_i
165
165
  ret = []
@@ -168,10 +168,10 @@ EOD
168
168
  end
169
169
  return ret
170
170
  elsif m = /\#<(\d+)<(.*?)>(\d+)>/.match(spec)
171
- debug "Using expansion rule #2"
171
+ debug { "Using expansion rule #2" }
172
172
  from = m[1].to_i
173
173
  to = m[3].to_i
174
- debug "Ruby code used for expansion: {|i| #{m[2]} }"
174
+ debug { "Ruby code used for expansion: {|i| #{m[2]} }" }
175
175
  code = eval "proc {|i| #{m[2]} }"
176
176
  ret = []
177
177
  from.upto(to) do |i|
@@ -179,13 +179,13 @@ EOD
179
179
  end
180
180
  return ret
181
181
  elsif m = /\#<\s*(\w+)\s*=\s*(\d+)\s*<(.*?)>\s*(\d+)\s*>/.match(spec)
182
- debug "Using expansion rule #3"
182
+ debug { "Using expansion rule #3" }
183
183
  var = m[1]
184
184
  from = m[2].to_i
185
185
  to = m[4].to_i
186
186
  # Then we replace all occurences of the variable
187
187
  literal = '"' + m[3].gsub(/\b#{var}\b/, '#{' + var + '}') + '"'
188
- debug "Ruby code used for expansion: {|#{var}| #{literal} }"
188
+ debug { "Ruby code used for expansion: {|#{var}| #{literal} }" }
189
189
  code = eval "proc {|#{var}| #{literal} }"
190
190
  ret = []
191
191
  from.upto(to) do |i|
@@ -197,10 +197,12 @@ EOD
197
197
  return [spec]
198
198
  rescue Exception => ex
199
199
  # In case something went wrong in the eval.
200
- warn "An error occured during expansion of '#{spec}': #{ex.message}"
201
- debug "Error backtrace: #{ex.backtrace.join "\n"}"
202
- warn "Ignoring, but you're nearly garanteed something will "+
200
+ warn { "An error occured during expansion of '#{spec}': #{ex.message}" }
201
+ debug { "Error backtrace: #{ex.backtrace.join "\n"}" }
202
+ warn {
203
+ "Ignoring, but you're nearly garanteed something will "+
203
204
  "fail later on"
205
+ }
204
206
  return [spec]
205
207
  end
206
208
 
@@ -242,7 +244,7 @@ EOD
242
244
  # * keys inside _exclude_ are removed.
243
245
  # * _supp_info_ is added
244
246
  #
245
- # TODO: get the implementation back again.
247
+ # \todo get the implementation back again.
246
248
  def get_cached_entry(name, exclude = [], supp_info = {}, &code)
247
249
  raise YetUnimplemented
248
250
  state = save_state
@@ -33,7 +33,7 @@ for file in files.uniq
33
33
  begin
34
34
  require "ctioga2/data/backends/backends/#{file}"
35
35
  rescue Exception => e
36
- warn "There was a problem trying to load 'ctioga2/data/backends/backends/#{file}': "
37
- warn "#{e.inspect}"
36
+ warn { "There was a problem trying to load 'ctioga2/data/backends/backends/#{file}': " }
37
+ warn { "#{e.inspect}" }
38
38
  end
39
39
  end
@@ -25,7 +25,7 @@ require 'stringio'
25
25
 
26
26
  module CTioga2
27
27
 
28
- Version::register_svn_info('$Revision: 61 $', '$Date: 2009-05-29 01:00:56 +0200 (Fri, 29 May 2009) $')
28
+ Version::register_svn_info('$Revision: 151 $', '$Date: 2010-06-19 23:45:20 +0200 (Sat, 19 Jun 2010) $')
29
29
 
30
30
 
31
31
  module Data
@@ -50,6 +50,10 @@ EOD
50
50
  param_accessor :range, 'range',
51
51
  "Plotting X range", 'float-range',
52
52
  "The plotting X range, such as 0:2"
53
+
54
+ param_accessor :samples, 'samples',
55
+ "The number of samples", 'text',
56
+ "The number of samples"
53
57
 
54
58
  # This is called by the architecture to get the data. It splits
55
59
  # the set name into filename@cols, reads the file if necessary and
@@ -76,20 +80,31 @@ EOD
76
80
  def run_gnuplot(filename, overrides = @variables_overrides)
77
81
  date = File::mtime(filename)
78
82
  # Get it from the cache !
79
- debug "Running gnuplot on file #{filename}"
83
+ debug { "Running gnuplot on file #{filename}" }
80
84
  f = File.open(filename)
81
85
  # We open a bidirectionnal connection to gnuplot:
82
86
  gnuplot = IO.popen("gnuplot", "r+")
83
87
  output = ""
84
- gnuplot.puts "set term table"
88
+ ## \todo determine gnuplot version for choosing which one we
89
+ ## want to use.
90
+ # gnuplot.puts "set term table"
91
+ gnuplot.puts "set table"
92
+ if @samples
93
+ overrides ||= ""
94
+ overrides += ";set samples #{@samples}"
95
+ end
85
96
  for line in f
86
97
  next if line =~ /set\s+term/
87
98
  if overrides and line =~ /plot\s+/
88
- debug "Found a plot, inserting variable overrides: #{overrides}"
99
+ debug {
100
+ "Found a plot, inserting variable overrides: #{overrides}"
101
+ }
89
102
  line.gsub!(/plot\s+/, "#{overrides};plot ")
90
103
  end
91
104
  if @range and line =~ /plot\s+/
92
- debug "Found a plot, inserting range: #{@range}"
105
+ debug {
106
+ "Found a plot, inserting range: #{@range}"
107
+ }
93
108
  line.gsub!(/plot\s+(\[[^\]]+\])?/,
94
109
  "plot [#{@range}]")
95
110
  end
@@ -21,7 +21,7 @@ require 'Dobjects/Function'
21
21
 
22
22
  module CTioga2
23
23
 
24
- Version::register_svn_info('$Revision: 17 $', '$Date: 2009-04-28 22:22:22 +0200 (Tue, 28 Apr 2009) $')
24
+ Version::register_svn_info('$Revision: 155 $', '$Date: 2010-06-21 21:41:32 +0200 (Mon, 21 Jun 2010) $')
25
25
 
26
26
  module Data
27
27
 
@@ -36,7 +36,7 @@ module CTioga2
36
36
  This backend returns computations of mathematical formulas.
37
37
  EOD
38
38
 
39
- # TODO: make provisions for 3-D datasets. Ideas: x(t):y(t):z(t)
39
+ # \todo make provisions for 3-D datasets. Ideas: x(t):y(t):z(t)
40
40
  # for parametric plots ? (possibly x(t):y1(t):y2(t):...:yn(t)) ?
41
41
 
42
42
  param_accessor :samples, 'samples', "Samples", 'integer',
@@ -25,7 +25,7 @@ require 'stringio'
25
25
 
26
26
  module CTioga2
27
27
 
28
- Version::register_svn_info('$Revision: 17 $', '$Date: 2009-04-28 22:22:22 +0200 (Tue, 28 Apr 2009) $')
28
+ Version::register_svn_info('$Revision: 191 $', '$Date: 2010-11-07 15:53:08 +0100 (Sun, 07 Nov 2010) $')
29
29
 
30
30
 
31
31
  module Data
@@ -49,6 +49,7 @@ module CTioga2
49
49
  ".bz2" => "bunzip2 -c %s",
50
50
  ".lzma" => "unlzma -c %s",
51
51
  ".lz" => "unlzma -c %s",
52
+ ".xz" => "unxz -c %s",
52
53
  }
53
54
 
54
55
  include Dobjects
@@ -76,9 +77,14 @@ EOD
76
77
  'regexp',
77
78
  "The columns separator. Defaults to /\s+/"
78
79
 
80
+ param_accessor :param_regex, 'parameters', "Parameters parsing",
81
+ 'regexp',
82
+ "Regular expression for extracting parameters from a file. Defaults to nil (ie nothing)"
79
83
 
80
- # param_accessor :select, 'select', "Select lines", {:type => :string},
81
- # "Skips line where the code returns false"
84
+ param_accessor :header_line_regex, 'header-line',
85
+ 'Header line regular expression',
86
+ 'regexp',
87
+ "Regular expression indicating the header line (containing column names) (default /^##/"
82
88
 
83
89
  def initialize
84
90
  @dummy = nil
@@ -95,11 +101,20 @@ EOD
95
101
  # We don't split data by default.
96
102
  @split = false
97
103
 
104
+ @param_regex = nil
105
+
106
+ @header_line_regex = /^\#\#\s*/
107
+
98
108
  super()
99
109
 
100
110
  # Override Backend's cache - for now.
101
111
  @cache = {} # A cache file_name -> data
102
112
 
113
+ @param_cache = {} # Same thing as cache, but for parameters
114
+
115
+ @headers_cache = {} # Same thing as cache, but for header
116
+ # lines.
117
+
103
118
  end
104
119
 
105
120
  def extend(mod)
@@ -147,20 +162,20 @@ EOD
147
162
  # Try to find a compressed version
148
163
  for ext,method in UNCOMPRESSORS
149
164
  if File.readable? "#{file}#{ext}"
150
- info "Using compressed file #{file}#{ext} in stead of #{file}"
165
+ info { "Using compressed file #{file}#{ext} in stead of #{file}" }
151
166
  return IO.popen(method % "#{file}#{ext}")
152
167
  end
153
168
  end
154
169
  else
155
170
  for ext, method in UNCOMPRESSORS
156
171
  if file =~ /#{ext}$/
157
- info "Taking file #{file} as a compressed file"
172
+ info { "Taking file #{file} as a compressed file" }
158
173
  return IO.popen(method % file)
159
174
  end
160
175
  end
161
176
  return File::open(file)
162
177
  end
163
- error "Could not open #{file}"
178
+ error { "Could not open #{file}" }
164
179
  return nil
165
180
  end
166
181
 
@@ -182,11 +197,11 @@ EOD
182
197
  while line = io.gets
183
198
  line_number += 1
184
199
  if line =~ InvalidLineRE
185
- debug "Found invalid line at #{line_number}"
200
+ debug { "Found invalid line at #{line_number}" }
186
201
  if ! last_line_is_invalid
187
202
  # We begin a new set.
188
203
  cur_set += 1
189
- debug "Found set #{cur_set} at line #{line_number}"
204
+ debug { "Found set #{cur_set} at line #{line_number}" }
190
205
  if(cur_set > set)
191
206
  return str
192
207
  end
@@ -214,32 +229,99 @@ EOD
214
229
  else
215
230
  set = 1
216
231
  end
217
- debug "Trying to get set #{set} from file '#{filename}'"
232
+ debug { "Trying to get set #{set} from file '#{filename}'" }
218
233
  str = get_set_string(get_io_object(filename), set)
219
234
  return StringIO.new(str)
220
235
  end
221
236
  end
222
237
 
238
+ undef :param_regex=
239
+ # A proper writer for @param_regex
240
+ def param_regex=(val)
241
+ if val.is_a? Regexp
242
+ @param_regex = val
243
+ elsif val =~ /([^\\]|^)\(/ # Has capturing groups
244
+ @param_regex = /#{val}/
245
+ else # Treat as separator
246
+ @param_regex = /(\S+)\s*#{val}\s*(\S+)/
247
+ end
248
+ end
249
+
250
+ # Turns an array of comments into a hash[param] -> value
251
+ def parse_parameters(comments)
252
+ ret = {}
253
+ for line in comments
254
+ if line =~ @param_regex
255
+ ret[$1] = $2.to_f
256
+ end
257
+ end
258
+ return ret
259
+ end
260
+
261
+ # Turns an array of comments into a hash column name -> column
262
+ # number (1-based)
263
+ def parse_header_line(comments)
264
+ for line in comments
265
+ if line =~ @header_line_regex
266
+ colnames = line.gsub(@header_line_regex,'').split(@separator)
267
+ i = 1
268
+ ret = {}
269
+ for n in colnames
270
+ ret[n] = i
271
+ i += 1
272
+ end
273
+ return ret
274
+ end
275
+ end
276
+ return {}
277
+ end
278
+
223
279
  # Reads data from a file. If needed, extract the file from the
224
280
  # columns specification.
225
281
  #
226
- # TODO: the cache really should include things such as time of
282
+ # \todo the cache really should include things such as time of
227
283
  # last modification and various parameters that influence the
228
- # reading of the file.
284
+ # reading of the file, and the parameters read from the file
285
+ # using #parse_parameters
286
+ #
287
+ # \todo There should be a real global handling of meta-data
288
+ # extracted from files, so that they could be included for
289
+ # instance in the automatic labels ? (and we could have fun
290
+ # improving this one ?)
291
+ #
292
+ # \warning This needs Tioga r561
229
293
  def read_file(file)
230
294
  if file =~ /(.*)@.*/
231
295
  file = $1
232
296
  end
233
297
  name = file # As file will be modified.
234
298
  if ! @cache.key?(file) # Read the file if it is not cached.
299
+ comments = []
235
300
  fancy_read_options = {'index_col' => true,
236
301
  'skip_first' => @skip,
237
- 'sep' => @separator
302
+ 'sep' => @separator,
303
+ 'comment_out' => comments
238
304
  }
239
305
  io_set = get_io_set(file)
240
- debug "Fancy read '#{file}', options #{fancy_read_options.inspect}"
306
+ debug { "Fancy read '#{file}', options #{fancy_read_options.inspect}" }
241
307
  @cache[name] = Dvector.fancy_read(io_set, nil, fancy_read_options)
308
+ if @param_regex
309
+ # Now parsing params
310
+ @param_cache[name] = parse_parameters(comments)
311
+ info { "Read #{@param_cache[name].size} parameters from #{name}" }
312
+ debug { "Parameters read: #{@param_cache[name].inspect}" }
313
+ end
314
+ if @header_line_regex
315
+ @headers_cache[name] = parse_header_line(comments)
316
+ info { "Read #{@headers_cache[name].size} column names from #{name}" }
317
+ debug { "Got: #{@headers_cache[name].inspect}" }
318
+ end
242
319
  end
320
+ ## @todo These are not very satisfying; ideally, the data
321
+ ## information should be embedded into @cache[name] rather
322
+ ## than as external variables. Well...
323
+ @current_parameters = @param_cache[name]
324
+ @current_header = @headers_cache[name]
243
325
  return @cache[name]
244
326
  end
245
327
 
@@ -268,17 +350,30 @@ EOD
268
350
  end
269
351
 
270
352
  return Dataset.dataset_from_spec(set, col_spec) do |col|
271
- get_data_column(col, compute_formulas)
353
+ get_data_column(col, compute_formulas,
354
+ @current_parameters, @current_header)
272
355
  end
273
356
  end
274
357
 
275
358
  # Gets the data corresponding to the given column. If
276
359
  # _compute_formulas_ is true, the column specification is
277
360
  # taken to be a formula (in the spirit of gnuplot's)
278
- def get_data_column(column, compute_formulas = false)
361
+ def get_data_column(column, compute_formulas = false,
362
+ parameters = nil, header = nil)
279
363
  if compute_formulas
280
- formula = column.gsub(/\$(\d+)/, 'column[\1]')
281
- debug "Using formula #{formula} for column spec: #{column}"
364
+ formula = column
365
+ if parameters
366
+ for k,v in parameters
367
+ formula.gsub!(/\b#{k}\b/, v.to_s)
368
+ end
369
+ end
370
+ formula.gsub!(/\$(\d+)/, 'column[\1]')
371
+ if header
372
+ for k,v in header
373
+ formula.gsub!("$#{k}$", "column[#{v}]")
374
+ end
375
+ end
376
+ debug { "Using formula #{formula} for column spec: #{column}" }
282
377
  return Dvector.compute_formula(formula,
283
378
  @current_data,
284
379
  @included_modules)