optimus-ep 0.6.91 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/CHANGELOG +13 -0
  2. data/{License.txt → LICENSE} +1 -1
  3. data/{Manifest.txt → Manifest} +23 -11
  4. data/{README.txt → README} +1 -1
  5. data/Rakefile +9 -10
  6. data/autotest/discover.rb +1 -0
  7. data/bin/eprime2tabfile +10 -10
  8. data/bin/extract_timings +4 -4
  9. data/lib/eprimetab_parser.rb +3 -3
  10. data/lib/excel_parser.rb +2 -2
  11. data/lib/expression_parser/evaluators.rb +188 -0
  12. data/lib/expression_parser/expressions.rb +173 -0
  13. data/lib/log_file_parser.rb +9 -9
  14. data/lib/optimus.rb +30 -0
  15. data/lib/{eprime_data.rb → optimus_data.rb} +12 -29
  16. data/lib/{eprime_reader.rb → optimus_reader.rb} +27 -13
  17. data/lib/parsed_calculator.rb +92 -0
  18. data/lib/raw_tab_parser.rb +3 -3
  19. data/lib/runners/generic_runner.rb +7 -7
  20. data/lib/runners/yaml_template/option_parser.rb +33 -0
  21. data/lib/runners/yaml_template/runner.rb +19 -0
  22. data/lib/tabfile_parser.rb +6 -6
  23. data/lib/tabfile_writer.rb +7 -7
  24. data/lib/transformers/basic_transformer.rb +35 -24
  25. data/lib/transformers/column_calculator.rb +131 -326
  26. data/lib/transformers/multipasser.rb +10 -6
  27. data/lib/transformers/row_filter.rb +7 -12
  28. data/lib/transformers/timing_extractor.rb +3 -3
  29. data/lib/version.rb +3 -3
  30. data/lib/writers/stimtimes_writer.rb +6 -6
  31. data/optimus-ep.gemspec +37 -0
  32. data/spec/eprimetab_parser_spec.rb +7 -7
  33. data/spec/excel_parser_spec.rb +6 -6
  34. data/spec/expression_parser/evaluators_spec.rb +241 -0
  35. data/spec/expression_parser/expressions_spec.rb +119 -0
  36. data/spec/log_file_parser_spec.rb +30 -30
  37. data/spec/{eprime_data_spec.rb → optimus_data_spec.rb} +20 -20
  38. data/spec/{eprime_reader_spec.rb → optimus_reader_spec.rb} +36 -24
  39. data/spec/parsed_calculator_spec.rb +112 -0
  40. data/spec/raw_tab_parser_spec.rb +26 -0
  41. data/spec/runners/generic_runner_spec.rb +5 -12
  42. data/spec/runners/yaml_template/option_parser_spec.rb +25 -0
  43. data/spec/runners/yaml_template/runner_spec.rb +20 -0
  44. data/spec/samples/optimus_log.txt +103 -103
  45. data/spec/samples/optimus_log_utf16le.txt +0 -0
  46. data/spec/samples/raw_tsv.txt +4 -0
  47. data/spec/spec_helper.rb +75 -12
  48. data/spec/tabfile_parser_spec.rb +18 -18
  49. data/spec/tabfile_writer_spec.rb +12 -12
  50. data/spec/transformers/basic_transformer_spec.rb +18 -8
  51. data/spec/transformers/column_calculator_spec.rb +109 -364
  52. data/spec/transformers/multipasser_spec.rb +14 -7
  53. data/spec/transformers/row_filter_spec.rb +11 -6
  54. data/spec/transformers/timing_extractor_spec.rb +8 -8
  55. data/spec/writers/stimtimes_writer_spec.rb +3 -3
  56. metadata +103 -50
  57. data/History.txt +0 -45
  58. data/lib/calculator.rb +0 -51
  59. data/lib/eprime.rb +0 -24
  60. data/spec/calculator_spec.rb +0 -70
data/CHANGELOG ADDED
@@ -0,0 +1,13 @@
1
+ v.0.8.0 Compatibility Warning: Lots of stuff has changed with the way column definition strings are computed. Test your existing scripts after updating! Architecture changes: Completely rewrote parser. String-based expressions now deprecate lambdas, though they'll continue to work in the future. This change fixes lots of odd bugs in defining computed columns and filters. Bug fixes: The --columns and --filter-columns options for eprime2tabfile now work.
2
+
3
+ v0.6.9.1 Bug fix: Fix for parsing eprime log files in which leaf frames don't occur at the highest log level
4
+
5
+ v0.6.9. New features: Supports parsing raw tab-delmimted files; Allows Procs as starting values for ComputedColumns. Bug fixes: No longer jumbles the order of Eprime log files
6
+
7
+ v0.6.5. New features: Speed! Speed! Speed! Should be something like 10x faster. Procs are now allowed in ComputedColumns -- so if you want to do really arbitrary things in your column computation, have at it.
8
+
9
+ v0.6.0. New features: Added extract_timings, a script to pull stimulus timing data from eprime files; Added a GenericRunner -- a class that greatly eases end-to-end transformation of eprime data. See extract_timings for an example of its use.
10
+
11
+ v0.5.5. New features: Supports making multiple passes through data, to allow extracting multiple stimuli that occur on the same row; Created a general-purpose stimulus extractor to pull data out in the format: stimulus \t onset__time \t offset__time. Architectural changes: Created a BasicTransformer that performs all of the basic operations to datasets: column calculation, row filtering, and multipass; Moved ColumnCalculator, RowFilter, and Multipasser into a Transformers module; Support release via hoe / rubygems
12
+
13
+ v0.5. First public gem release; Supports converting general Eprime files into tab-delimited files; Supports converting Eprime files into AFNI stim_times files
@@ -1,5 +1,5 @@
1
1
  Optimus: Libraries and utilities for interacting with E-Prime data files
2
- Copyright (C) 2008 Board of Regents of the University of Wisconsin System
2
+ Copyright (C) 2008-09 Board of Regents of the University of Wisconsin System
3
3
 
4
4
  This program is free software; you can redistribute it and/or
5
5
  modify it under the terms of version 2 of the GNU General Public
@@ -1,20 +1,25 @@
1
+ CHANGELOG
1
2
  GPL.txt
2
- History.txt
3
- License.txt
4
- Manifest.txt
5
- README.txt
3
+ LICENSE
4
+ Manifest
5
+ README
6
6
  Rakefile
7
+ autotest/discover.rb
7
8
  bin/eprime2tabfile
8
9
  bin/extract_timings
9
- lib/calculator.rb
10
- lib/eprime.rb
11
- lib/eprime_data.rb
12
- lib/eprime_reader.rb
13
10
  lib/eprimetab_parser.rb
14
11
  lib/excel_parser.rb
12
+ lib/expression_parser/evaluators.rb
13
+ lib/expression_parser/expressions.rb
15
14
  lib/log_file_parser.rb
15
+ lib/optimus.rb
16
+ lib/optimus_data.rb
17
+ lib/optimus_reader.rb
18
+ lib/parsed_calculator.rb
16
19
  lib/raw_tab_parser.rb
17
20
  lib/runners/generic_runner.rb
21
+ lib/runners/yaml_template/option_parser.rb
22
+ lib/runners/yaml_template/runner.rb
18
23
  lib/tabfile_parser.rb
19
24
  lib/tabfile_writer.rb
20
25
  lib/transformers/basic_transformer.rb
@@ -24,18 +29,25 @@ lib/transformers/row_filter.rb
24
29
  lib/transformers/timing_extractor.rb
25
30
  lib/version.rb
26
31
  lib/writers/stimtimes_writer.rb
27
- spec/calculator_spec.rb
28
- spec/eprime_data_spec.rb
29
- spec/eprime_reader_spec.rb
30
32
  spec/eprimetab_parser_spec.rb
31
33
  spec/excel_parser_spec.rb
34
+ spec/expression_parser/evaluators_spec.rb
35
+ spec/expression_parser/expressions_spec.rb
32
36
  spec/log_file_parser_spec.rb
37
+ spec/optimus_data_spec.rb
38
+ spec/optimus_reader_spec.rb
39
+ spec/parsed_calculator_spec.rb
40
+ spec/raw_tab_parser_spec.rb
33
41
  spec/runners/generic_runner_spec.rb
42
+ spec/runners/yaml_template/option_parser_spec.rb
43
+ spec/runners/yaml_template/runner_spec.rb
34
44
  spec/samples/bad_excel_tsv.txt
35
45
  spec/samples/corrupt_log_file.txt
36
46
  spec/samples/eprime_tsv.txt
37
47
  spec/samples/excel_tsv.txt
38
48
  spec/samples/optimus_log.txt
49
+ spec/samples/optimus_log_utf16le.txt
50
+ spec/samples/raw_tsv.txt
39
51
  spec/samples/short_columns.txt
40
52
  spec/samples/sorted_columns.txt
41
53
  spec/samples/std_columns.txt
@@ -27,7 +27,7 @@ FIX (describe your package)
27
27
  (The GNU Public License, Version 2)
28
28
 
29
29
  Optimus: Libraries and utilities for interacting with E-Prime data files
30
- Copyright (C) 2008 Board of Regents of the University of Wisconsin System
30
+ Copyright (C) 2008-09 Board of Regents of the University of Wisconsin System
31
31
 
32
32
  This program is free software; you can redistribute it and/or
33
33
  modify it under the terms of version 2 of the GNU General Public
data/Rakefile CHANGED
@@ -1,12 +1,11 @@
1
- require 'rake'
2
- require 'spec/rake/spectask'
3
- #require 'config/requirements'
4
- require 'hoe'
5
- require 'config/hoe' # setup Hoe + all gem configuration
1
+ require 'echoe'
2
+ require 'lib/version'
6
3
 
7
- Dir['tasks/**/*.rake'].each { |rake| load rake }
8
-
9
- desc "Run specs"
10
- Spec::Rake::SpecTask.new('default') do |t|
11
- t.spec_files = FileList['spec/**/*.rb']
4
+ Echoe.new("optimus-ep", Optimus::VERSION::STRING) do |p|
5
+ p.author = "Nate Vack"
6
+ p.email = "njvack@wisc.edu"
7
+ p.summary = "Utilities to process behavioral data generated by E-Prime"
8
+ p.url = "http://github.com/njvack/optimus-ep"
9
+ p.runtime_dependencies = ["rparsec >=1.0"]
10
+ p.development_dependencies = ["rspec"]
12
11
  end
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
data/bin/eprime2tabfile CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Part of the Optimus package for managing E-Prime data
4
4
  #
5
- # Copyright (C) 2008 Board of Regents of the University of Wisconsin System
5
+ # Copyright (C) 2008-09 Board of Regents of the University of Wisconsin System
6
6
  #
7
7
  # Written by Nathan Vack <njvack@wisc.edu>, at the Waisman Laborotory for Brain
8
8
  # Imaging and Behavior, University of Wisconsin - Madison
@@ -10,9 +10,9 @@
10
10
  require 'rubygems'
11
11
  require 'optparse'
12
12
  gem 'optimus-ep'
13
- require 'eprime'
13
+ require 'optimus'
14
14
 
15
- module Eprime
15
+ module Optimus
16
16
  class LogToTabConverter
17
17
  attr_reader :options
18
18
  attr_accessor :data_out
@@ -38,12 +38,12 @@ module Eprime
38
38
  end
39
39
 
40
40
  def convert
41
- eprime = Eprime::Data.new(@columns, :ignore_warnings => @options[:force])
41
+ optimus = Optimus::Data.new(@columns, :ignore_warnings => @options[:force])
42
42
  @options[:files].each do |filename|
43
43
  begin
44
44
  File.open(filename, 'r') do |f|
45
- reader = Eprime::Reader.new(f, {:columns => @columns, :force => @options[:force]})
46
- eprime.merge!(reader.eprime_data)
45
+ reader = Optimus::Reader.new(f, {:columns => @columns, :force => @options[:force]})
46
+ optimus.merge!(reader.optimus_data)
47
47
  end
48
48
  rescue Exception => e
49
49
  @err.puts e.message
@@ -51,7 +51,7 @@ module Eprime
51
51
  exit(1)
52
52
  end
53
53
  end
54
- writer = Eprime::TabfileWriter.new(eprime, data_out, {
54
+ writer = Optimus::TabfileWriter.new(optimus, data_out, {
55
55
  :write_top_line => @options[:add_filename_line],
56
56
  :columns => @columns
57
57
  })
@@ -78,7 +78,7 @@ module Eprime
78
78
  def option_parser(option_hash, args)
79
79
  opts = OptionParser.new
80
80
 
81
- opts.banner = "Usage: eprimelog2tabfile [options] INPUT_FILES"
81
+ opts.banner = "Usage: optimuslog2tabfile [options] INPUT_FILES"
82
82
  opts.separator ""
83
83
 
84
84
  opts.on('-o', '--outfile=OUTFILE', String,
@@ -143,9 +143,9 @@ module Eprime
143
143
  end
144
144
 
145
145
  begin
146
- conv = Eprime::LogToTabConverter.new(ARGV)
146
+ conv = Optimus::LogToTabConverter.new(ARGV)
147
147
  rescue Exception => e
148
- STDERR.puts e.message+"\nrun eprimelog2tabfile --help for options\n"
148
+ STDERR.puts e.message+"\nrun optimuslog2tabfile --help for options\n"
149
149
  exit(1)
150
150
  end
151
151
 
data/bin/extract_timings CHANGED
@@ -2,18 +2,18 @@
2
2
 
3
3
  # Part of the Optimus package for managing E-Prime data
4
4
  #
5
- # Copyright (C) 2008 Board of Regents of the University of Wisconsin System
5
+ # Copyright (C) 2008-09 Board of Regents of the University of Wisconsin System
6
6
  #
7
7
  # Written by Nathan Vack <njvack@wisc.edu>, at the Waisman Laborotory for Brain
8
8
  # Imaging and Behavior, University of Wisconsin - Madison
9
9
 
10
10
  require 'rubygems'
11
11
  require 'optparse'
12
- gem 'optimus-ep'
13
- require 'runners/generic_runner'
12
+ #gem 'optimus-ep'
13
+ require 'lib/runners/generic_runner'
14
14
 
15
15
  begin
16
- txr = Eprime::Runners::GenericRunner.new(Eprime::Transformers::TimingExtractor, ARGV)
16
+ txr = Optimus::Runners::GenericRunner.new(Optimus::Transformers::TimingExtractor, ARGV)
17
17
  txr.process!
18
18
  rescue ArgumentError => e
19
19
  STDERR.puts e.message
@@ -1,6 +1,6 @@
1
1
  # Part of the Optimus package for managing E-Prime data
2
2
  #
3
- # Copyright (C) 2008 Board of Regents of the University of Wisconsin System
3
+ # Copyright (C) 2008-09 Board of Regents of the University of Wisconsin System
4
4
  #
5
5
  # Written by Nathan Vack <njvack@wisc.edu>, at the Waisman Laborotory for Brain
6
6
  # Imaging and Behavior, University of Wisconsin - Madison
@@ -9,9 +9,9 @@
9
9
 
10
10
  require 'tabfile_parser'
11
11
 
12
- module Eprime
12
+ module Optimus
13
13
  class Reader
14
- class EprimetabParser < TabfileParser
14
+ class OptimustabParser < TabfileParser
15
15
  def initialize(file, options = {})
16
16
  options = options.merge(:skip_lines => 3)
17
17
  super(file, options)
data/lib/excel_parser.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # Part of the Optimus package for managing E-Prime data
2
2
  #
3
- # Copyright (C) 2008 Board of Regents of the University of Wisconsin System
3
+ # Copyright (C) 2008-09 Board of Regents of the University of Wisconsin System
4
4
  #
5
5
  # Written by Nathan Vack <njvack@wisc.edu>, at the Waisman Laborotory for Brain
6
6
  # Imaging and Behavior, University of Wisconsin - Madison
@@ -9,7 +9,7 @@
9
9
 
10
10
  require 'tabfile_parser'
11
11
 
12
- module Eprime
12
+ module Optimus
13
13
  class Reader
14
14
  class ExcelParser < TabfileParser
15
15
  def initialize(file, options = {})
@@ -0,0 +1,188 @@
1
+ # Part of the Optimus package for managing E-Prime data
2
+ #
3
+ # Copyright (C) 2008-09 Board of Regents of the University of Wisconsin System
4
+ #
5
+ # Written by Nathan Vack <njvack@wisc.edu>, at the Waisman Laborotory for Brain
6
+ # Imaging and Behavior, University of Wisconsin - Madison
7
+ #
8
+ # Functions that actually handle evaluating operands and such.
9
+
10
+ module Optimus
11
+ module ParsedCalculator
12
+ module Evaluators
13
+ NaN = 0.0/0.0
14
+
15
+ class ArgList
16
+ include Enumerable
17
+ attr_accessor :args
18
+ def initialize(*args)
19
+ @args = args
20
+ end
21
+
22
+ def each(&block)
23
+ @args.each(&block)
24
+ end
25
+
26
+ def all_num?
27
+ @args.all? {|v| v.kind_of? Numeric }
28
+ end
29
+
30
+ def cast_for_comparison
31
+ @args.map {|v| floatify(v) }
32
+ end
33
+
34
+ def bool_cast
35
+ @args.map {|v| v.to_s.strip == '' ? false : v }
36
+ end
37
+
38
+ private
39
+ def floatify(arg)
40
+ return arg.to_f if arg.kind_of? Numeric
41
+ return arg.to_s.to_f if arg.to_s =~ /^-?\d+\.?\d*$/
42
+ return arg
43
+ end
44
+ end
45
+
46
+ module Prefix
47
+ Neg = lambda {|rval|
48
+ if rval.kind_of? Numeric
49
+ return -rval
50
+ else
51
+ return NaN
52
+ end
53
+ }
54
+
55
+ Not = lambda {|rval|
56
+ args = ArgList.new(rval)
57
+ cr = args.bool_cast[0]
58
+ return (not(cr))
59
+ }
60
+
61
+ OpTable = {
62
+ :- => Neg,
63
+ :not => Not
64
+ }
65
+ end # module Prefix
66
+
67
+ # Actual functions to evaluate binary expressions such as
68
+ # 1+1 and 5%3.
69
+ # Here is where we get to say what our operators actually do!
70
+ module Binary
71
+ Plus = lambda {|lval, rval|
72
+ args = ArgList.new(lval, rval)
73
+ return lval+rval if args.all_num?
74
+ return NaN
75
+ }
76
+
77
+ Minus = lambda {|lval, rval|
78
+ args = ArgList.new(lval, rval)
79
+ return lval-rval if args.all_num?
80
+ return NaN
81
+ }
82
+
83
+ Times = lambda {|lval, rval|
84
+ args = ArgList.new(lval, rval)
85
+ return lval*rval if args.all_num?
86
+ return NaN
87
+ }
88
+
89
+ Div = lambda {|lval, rval|
90
+ args = ArgList.new(lval, rval)
91
+ return NaN if rval.to_f == 0.0
92
+ return lval.to_f/rval.to_f
93
+ }
94
+
95
+ Mod = lambda {|lval, rval|
96
+ args = ArgList.new(lval, rval)
97
+ return lval%rval if args.all_num?
98
+ return NaN
99
+ }
100
+
101
+ Concat = lambda {|lval, rval|
102
+ return lval.to_s+rval.to_s
103
+ }
104
+
105
+ And = lambda {|lval, rval|
106
+ args = ArgList.new(lval, rval)
107
+ cl, cr = args.bool_cast
108
+ return (cl and cr)
109
+ }
110
+
111
+ Or = lambda {|lval, rval|
112
+ args = ArgList.new(lval, rval)
113
+ cl, cr = args.bool_cast
114
+ return (cl or cr)
115
+ }
116
+
117
+ Equals = lambda {|lval, rval|
118
+ args = ArgList.new(lval, rval)
119
+ cl, cr = args.cast_for_comparison
120
+ return cl == cr
121
+ }
122
+
123
+ NotEquals = lambda {|lval, rval|
124
+ args = ArgList.new(lval, rval)
125
+ cl, cr = args.cast_for_comparison
126
+ return cl != cr
127
+ }
128
+
129
+ GreaterThan = lambda {|lval, rval|
130
+ args = ArgList.new(lval, rval)
131
+ cl, cr = args.cast_for_comparison
132
+ begin
133
+ return cl > cr
134
+ rescue ArgumentError => e
135
+ return false
136
+ end
137
+ }
138
+
139
+ LessThan = lambda {|lval, rval|
140
+ args = ArgList.new(lval, rval)
141
+ cl, cr = args.cast_for_comparison
142
+ begin
143
+ return cl < cr
144
+ rescue ArgumentError => e
145
+ return false
146
+ end
147
+ }
148
+
149
+ GreaterThanEquals = lambda {|lval, rval|
150
+ args = ArgList.new(lval, rval)
151
+ cl, cr = args.cast_for_comparison
152
+ begin
153
+ return cl >= cr
154
+ rescue ArgumentError => e
155
+ return false
156
+ end
157
+ }
158
+
159
+ LessThanEquals = lambda {|lval, rval|
160
+ args = ArgList.new(lval, rval)
161
+ cl, cr = args.cast_for_comparison
162
+ begin
163
+ return cl <= cr
164
+ rescue ArgumentError => e
165
+ return false
166
+ end
167
+ }
168
+
169
+ OpTable = {
170
+ :+ => Plus,
171
+ :- => Minus,
172
+ :* => Times,
173
+ :/ => Div,
174
+ :% => Mod,
175
+ :& => Concat,
176
+ :and => And,
177
+ :or => Or,
178
+ '='.to_sym => Equals,
179
+ '!='.to_sym => NotEquals,
180
+ :> => GreaterThan,
181
+ :< => LessThan,
182
+ :>= => GreaterThanEquals,
183
+ :<= => LessThanEquals
184
+ }
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,173 @@
1
+ # Part of the Optimus package for managing E-Prime data
2
+ #
3
+ # Copyright (C) 2008-09 Board of Regents of the University of Wisconsin System
4
+ #
5
+ # Written by Nathan Vack <njvack@wisc.edu>, at the Waisman Laborotory for Brain
6
+ # Imaging and Behavior, University of Wisconsin - Madison
7
+ #
8
+ # Expressions for the ParsedCalculator
9
+ require 'expression_parser/evaluators'
10
+
11
+ module Optimus
12
+ module ParsedCalculator
13
+ NaN = 0.0/0.0
14
+ class Expr
15
+ # All of our literals, etc will ineherit from Expr. This will imbue
16
+ # them with the magic to work with our unary and binary operators.
17
+ BINARY_OPERATORS=[:+, :-, :*, :/, :%, :&, :>, :>=, :<, :<=]
18
+ BINARY_OPERATORS.each do |op|
19
+ define_method(op) { |other|
20
+ return BinaryExpr.new(self, op, other)
21
+ }
22
+ end
23
+
24
+ def logical_and(other)
25
+ return BinaryExpr.new(self, :and, other)
26
+ end
27
+
28
+ def logical_or(other)
29
+ return BinaryExpr.new(self, :or, other)
30
+ end
31
+
32
+ def eq(other)
33
+ return BinaryExpr.new(self, "=".to_sym, other)
34
+ end
35
+
36
+ def neq(other)
37
+ return BinaryExpr.new(self, '!='.to_sym, other)
38
+ end
39
+
40
+ # Prefixes
41
+ def -@
42
+ return PrefixExpr.new(:-, self)
43
+ end
44
+
45
+ def logical_not
46
+ return KeywordPrefixExpr.new(:not, self)
47
+ end
48
+
49
+ def to_bool(*args)
50
+ val = evaluate(*args)
51
+ return false if val == ''
52
+ return val
53
+ end
54
+ end
55
+
56
+ class BinaryExpr < Expr
57
+ include Evaluators::Binary
58
+
59
+ attr_reader :left, :op, :right
60
+ def initialize(left, op, right)
61
+ @left = left
62
+ @op = op
63
+ @right = right
64
+ end
65
+
66
+ def to_s
67
+ "(#{@left} #{@op} #{@right})"
68
+ end
69
+
70
+ def evaluate(*args)
71
+ lval = @left.evaluate(*args)
72
+ rval = @right.evaluate(*args)
73
+ return OpTable[@op].call(lval, rval)
74
+ end
75
+ end
76
+
77
+ class PrefixExpr < Expr
78
+ include Evaluators::Prefix
79
+ attr_reader :op, :right
80
+ def initialize(op, right)
81
+ @op = op
82
+ @right = right
83
+ end
84
+
85
+ def to_s
86
+ "#{@op}(#{@right})"
87
+ end
88
+
89
+ def evaluate(*args)
90
+ rval = @right.evaluate(*args)
91
+ return OpTable[@op].call(rval)
92
+ end
93
+
94
+ end
95
+
96
+ class KeywordPrefixExpr < PrefixExpr
97
+ def to_s
98
+ "#{@op} (#{@right})"
99
+ end
100
+ end
101
+
102
+ class NumberLiteral < Expr
103
+ def initialize(token)
104
+ @token = token
105
+ end
106
+
107
+ def to_s
108
+ @token
109
+ end
110
+
111
+ def evaluate(*args)
112
+ @token.to_f
113
+ end
114
+ end
115
+
116
+ class StringLiteral < Expr
117
+
118
+ def initialize(token)
119
+ @token = token
120
+ end
121
+
122
+ def to_s
123
+ "'#{@token}'"
124
+ end
125
+
126
+ def evaluate(*args)
127
+ @token
128
+ end
129
+ end
130
+
131
+ class ColumnReference < Expr
132
+ def initialize(name)
133
+ @name = name
134
+ end
135
+
136
+ def to_s
137
+ "{#{@name}}"
138
+ end
139
+
140
+ def evaluate(*args)
141
+ options = args.last || {}
142
+ row = options[:row] || {}
143
+ computed_columns = options[:computed_columns] || {}
144
+ seen_columns = options[:seen_columns] || []
145
+ if seen_columns.include?(@name)
146
+ raise EvaluationLoopError.new(
147
+ "Loop error - #{@name} depends on itself: [#{seen_columns.join(', ')}]"
148
+ )
149
+ end
150
+
151
+ if !row[@name] and computed_columns.include?(@name)
152
+ row[@name] = computed_columns[@name].evaluate(
153
+ :row => row,
154
+ :computed_columns => computed_columns,
155
+ :seen_columns => ([@name] + seen_columns)
156
+ )
157
+ end
158
+ return magic_cast(row[@name])
159
+ end
160
+
161
+ private
162
+ def magic_cast(value)
163
+ new_val = value.to_s.strip
164
+ new_val = new_val.to_f if numlike?(new_val)
165
+ return new_val
166
+ end
167
+
168
+ def numlike?(value)
169
+ value.to_s =~ /^-?\d+\.?\d*$/
170
+ end
171
+ end # class ColumnReference
172
+ end
173
+ end
@@ -1,20 +1,20 @@
1
1
  # Part of the Optimus package for managing E-Prime data
2
2
  #
3
- # Copyright (C) 2008 Board of Regents of the University of Wisconsin System
3
+ # Copyright (C) 2008-09 Board of Regents of the University of Wisconsin System
4
4
  #
5
5
  # Written by Nathan Vack <njvack@wisc.edu>, at the Waisman Laborotory for Brain
6
6
  # Imaging and Behavior, University of Wisconsin - Madison
7
7
 
8
- module Eprime
8
+ module Optimus
9
9
  class Reader
10
10
 
11
11
  # Reads and parses E-Prime log files (the ones that start with
12
- # *** Header Start ***) and transforms them into an Eprime::Data structure
12
+ # *** Header Start ***) and transforms them into an Optimus::Data structure
13
13
 
14
14
 
15
15
  class LogfileParser
16
- # Handles parsing eprime log files, which are essentially a blow-by-blow
17
- # log of everything that happened during an eprime run.
16
+ # Handles parsing optimus log files, which are essentially a blow-by-blow
17
+ # log of everything that happened during an optimus run.
18
18
 
19
19
  FRAME_START = '*** LogFrame Start ***'
20
20
  FRAME_END = '*** LogFrame End ***'
@@ -46,7 +46,7 @@ module Eprime
46
46
  set_counters!
47
47
  end
48
48
 
49
- def to_eprime
49
+ def to_optimus
50
50
  begin
51
51
  if @frames.nil? or @frames.empty?
52
52
  make_frames!
@@ -56,7 +56,7 @@ module Eprime
56
56
  end
57
57
 
58
58
  @columns ||= @found_cols.names
59
- data = Eprime::Data.new(@columns)
59
+ data = Optimus::Data.new(@columns)
60
60
  self.leaf_frames.each do |frame|
61
61
  row = data.add_row
62
62
  @found_cols.names_with_cols.each do |pair|
@@ -78,7 +78,7 @@ module Eprime
78
78
  end
79
79
 
80
80
  def self.can_parse?(lines)
81
- lines[0].include?('*** Header Start ***')
81
+ lines[0].include?(HEADER_START)
82
82
  end
83
83
 
84
84
  private
@@ -294,4 +294,4 @@ module Eprime
294
294
  end
295
295
  end # Class LogfileParser
296
296
  end # Class Reader
297
- end # Module Eprime
297
+ end # Module Optimus