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.
- 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
|