optimus-ep 0.6.91 → 0.8.0
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.
- data/CHANGELOG +13 -0
- data/{License.txt → LICENSE} +1 -1
- data/{Manifest.txt → Manifest} +23 -11
- data/{README.txt → README} +1 -1
- data/Rakefile +9 -10
- data/autotest/discover.rb +1 -0
- data/bin/eprime2tabfile +10 -10
- data/bin/extract_timings +4 -4
- data/lib/eprimetab_parser.rb +3 -3
- data/lib/excel_parser.rb +2 -2
- data/lib/expression_parser/evaluators.rb +188 -0
- data/lib/expression_parser/expressions.rb +173 -0
- data/lib/log_file_parser.rb +9 -9
- data/lib/optimus.rb +30 -0
- data/lib/{eprime_data.rb → optimus_data.rb} +12 -29
- data/lib/{eprime_reader.rb → optimus_reader.rb} +27 -13
- data/lib/parsed_calculator.rb +92 -0
- data/lib/raw_tab_parser.rb +3 -3
- data/lib/runners/generic_runner.rb +7 -7
- data/lib/runners/yaml_template/option_parser.rb +33 -0
- data/lib/runners/yaml_template/runner.rb +19 -0
- data/lib/tabfile_parser.rb +6 -6
- data/lib/tabfile_writer.rb +7 -7
- data/lib/transformers/basic_transformer.rb +35 -24
- data/lib/transformers/column_calculator.rb +131 -326
- data/lib/transformers/multipasser.rb +10 -6
- data/lib/transformers/row_filter.rb +7 -12
- data/lib/transformers/timing_extractor.rb +3 -3
- data/lib/version.rb +3 -3
- data/lib/writers/stimtimes_writer.rb +6 -6
- data/optimus-ep.gemspec +37 -0
- data/spec/eprimetab_parser_spec.rb +7 -7
- data/spec/excel_parser_spec.rb +6 -6
- data/spec/expression_parser/evaluators_spec.rb +241 -0
- data/spec/expression_parser/expressions_spec.rb +119 -0
- data/spec/log_file_parser_spec.rb +30 -30
- data/spec/{eprime_data_spec.rb → optimus_data_spec.rb} +20 -20
- data/spec/{eprime_reader_spec.rb → optimus_reader_spec.rb} +36 -24
- data/spec/parsed_calculator_spec.rb +112 -0
- data/spec/raw_tab_parser_spec.rb +26 -0
- data/spec/runners/generic_runner_spec.rb +5 -12
- data/spec/runners/yaml_template/option_parser_spec.rb +25 -0
- data/spec/runners/yaml_template/runner_spec.rb +20 -0
- data/spec/samples/optimus_log.txt +103 -103
- data/spec/samples/optimus_log_utf16le.txt +0 -0
- data/spec/samples/raw_tsv.txt +4 -0
- data/spec/spec_helper.rb +75 -12
- data/spec/tabfile_parser_spec.rb +18 -18
- data/spec/tabfile_writer_spec.rb +12 -12
- data/spec/transformers/basic_transformer_spec.rb +18 -8
- data/spec/transformers/column_calculator_spec.rb +109 -364
- data/spec/transformers/multipasser_spec.rb +14 -7
- data/spec/transformers/row_filter_spec.rb +11 -6
- data/spec/transformers/timing_extractor_spec.rb +8 -8
- data/spec/writers/stimtimes_writer_spec.rb +3 -3
- metadata +103 -50
- data/History.txt +0 -45
- data/lib/calculator.rb +0 -51
- data/lib/eprime.rb +0 -24
- 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
|
data/{License.txt → LICENSE}
RENAMED
@@ -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
|
data/{Manifest.txt → Manifest}
RENAMED
@@ -1,20 +1,25 @@
|
|
1
|
+
CHANGELOG
|
1
2
|
GPL.txt
|
2
|
-
|
3
|
-
|
4
|
-
|
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
|
data/{README.txt → README}
RENAMED
@@ -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 '
|
2
|
-
require '
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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 '
|
13
|
+
require 'optimus'
|
14
14
|
|
15
|
-
module
|
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
|
-
|
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 =
|
46
|
-
|
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 =
|
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:
|
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 =
|
146
|
+
conv = Optimus::LogToTabConverter.new(ARGV)
|
147
147
|
rescue Exception => e
|
148
|
-
STDERR.puts e.message+"\nrun
|
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 =
|
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
|
data/lib/eprimetab_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,9 +9,9 @@
|
|
9
9
|
|
10
10
|
require 'tabfile_parser'
|
11
11
|
|
12
|
-
module
|
12
|
+
module Optimus
|
13
13
|
class Reader
|
14
|
-
class
|
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
|
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
|
data/lib/log_file_parser.rb
CHANGED
@@ -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
|
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
|
12
|
+
# *** Header Start ***) and transforms them into an Optimus::Data structure
|
13
13
|
|
14
14
|
|
15
15
|
class LogfileParser
|
16
|
-
# Handles parsing
|
17
|
-
# log of everything that happened during an
|
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
|
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 =
|
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?(
|
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
|
297
|
+
end # Module Optimus
|