public
Description: Easy Linger output processing in Ruby
Homepage: http://pealco.net/code
Clone URL: git://github.com/pealco/linger-process.git
linger-process / linger-process.rb
100644 141 lines (116 sloc) 4.002 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
class Experiment
 
  attr_reader :sentences
 
  def initialize(experiment, factors, options = {})
    
    default_dir = "./data/"
    default_columns = [:words, :word_lengths, :word_positions, :regions, :experiment,
                :subject, :item, :condition, :sentence_number, :list_position,
                :reading_times, :log_reading_times, :accuracy]
                
    data_directory = options.fetch(:dir, default_dir)
    columns = options.fetch(:columns, default_columns)
    @experiments = ([experiment] + ["filler"]).flatten
    @factors = factors
    @columns = columns
    
    @sentences = []
 
    Dir.foreach(data_directory) do |file|
      if file =~ /(\d+)\.dat/
        puts file
        File.open(data_directory + file) do |current_file|
          sentence = Sentence.new
          list_position = 0
          while line = current_file.gets
            columns = line.split
if @experiments.any? {|exp| columns[1] == exp}
              if columns[4] != "?"
                sentence[:words] << columns[5]
                sentence[:regions] << columns[6]
                sentence[:reading_times] << columns[7]
              elsif columns[4] == "?"
                sentence[:subject] = columns[0]
                sentence[:experiment] = columns[1]
                sentence[:item] = columns[2]
                sentence[:condition] = columns[3]
                sentence[:factors] = self.factors(sentence[:condition])
                sentence[:accuracy] = columns[6]
                sentence[:list_position] = (list_position += 1)
 
                @sentences << sentence
                sentence = Sentence.new
              end
            end
          end
        end
      end
    end
  end
 
  def factors(condition)
    @factors[condition].nil? ? %w(NA NA NA).join("\t") : @factors[condition].join("\t")
  end
 
  def to_s
    out = (@columns.map {|column| column.to_s}).join("\t") + "\n" # The header line. Doesn't expand factors.
    @sentences.each do |s|
      s.compute
      s.length.times do |word|
        line = self.output_columns(s, word)
        out << line.join("\t") + "\n"
      end
    end
    
    return out
  end
 
  def to_file(file)
    File.new(file, "w+").puts self
    puts "Created #{file}"
  end
 
  protected
  def output_columns(s, word)
    @columns.map {|column| s[column].class == Array ? s[column][word] : s[column]}
  end
    
end
 
class Sentence
  
  def initialize
    @attributes = {:words => [],
                   :word_lengths => nil,
                   :word_positions => nil,
                   :regions => [],
                   :experiment => nil,
                   :subject => nil,
                   :item => nil,
                   :condition => nil,
                   :factors => nil,
                   :sentence_number => nil,
                   :list_position => nil,
                   :reading_times => [],
                   :log_reading_times => [],
                   :accuracy => nil}
  end
  
  def [](key)
    @attributes[key]
  end
  
  def []=(key, value)
    @attributes[key] = value
  end
  
  def compute
    self.word_lengths
    self.condition
    self.word_positions
    self.regions
    self.log_reading_times
  end
  
  def length
    @attributes[:words].length
  end
  
  protected
  def word_lengths
    @attributes[:word_lengths] = @attributes[:words].map {|word| word.length}
  end
 
  def condition
    @attributes[:condition] = "NA" if @attributes[:condition] == "-"
  end
 
  def word_positions
    @attributes[:word_positions] = (1..@attributes[:words].length).to_a
  end
 
  def regions
    @attributes[:regions] = @attributes[:regions].map {|region| (region == "-" or region == "NA") ? "NA" : region[0,1]}
  end
  
  def log_reading_times
    @attributes[:log_reading_times] = @attributes[:reading_times].map {|rt| Math::log(rt)}
  end
 
end