Class: Logfile

Inherits:
Object
  • Object
show all
Includes:
DefaultLogger
Defined in:
lib/logfile.rb

Overview

START OF CLASS ###################################################### An object that helps parse and format Behavioral Logfiles.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DefaultLogger

#setup_logger

Constructor Details

#initialize(path, *conditions) ⇒ Logfile

Returns a new instance of Logfile.

Raises:

  • (IOError)


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
# File 'lib/logfile.rb', line 22

def initialize(path, *conditions)
  @textfile = path
  @textfile_data = []
  @conditions = conditions.select {|cond| cond.respond_to? 'to_sym'  }
  
  # Add the keys of any hashes (the combined conditions) to the list of 
  # conditions and add the separate vectors to the list of combined_conditions
  @combined_conditions = []
  conditions.select {|cond| cond.respond_to? 'keys' }.each do |cond|
    cond.keys.collect {|key| @conditions << key }
    @combined_conditions << cond
  end
  
  raise IOError, "Can't find file #{path}" unless File.exist?(path)
  File.open(path, 'r').each do |line| 
    @textfile_data << line.split(/[\,\:\n\r]+/).each { |val| val.strip } 
  end
  
  raise IOError, "Problem reading #{@textfile} - no data found." if @textfile_data.empty?

  if @conditions.empty?
    raise ScriptError, "Could not set conditions #{conditions}" unless conditions.empty?
  end
  
  setup_logger

end

Instance Attribute Details

#conditionsObject

Conditions to extract time vectors from



14
15
16
# File 'lib/logfile.rb', line 14

def conditions
  @conditions
end

#csv_filenameObject

Filename for output csv



16
17
18
# File 'lib/logfile.rb', line 16

def csv_filename
  @csv_filename
end

#textfileObject (readonly)

Original Presentation Processed Logfile (.txt)



18
19
20
# File 'lib/logfile.rb', line 18

def textfile
  @textfile
end

#textfile_dataObject

An array of rows raw text data



12
13
14
# File 'lib/logfile.rb', line 12

def textfile_data
  @textfile_data
end

#vectorsObject (readonly)

A hash of Onset Vectors keyed by condition



20
21
22
# File 'lib/logfile.rb', line 20

def vectors
  @vectors
end

Class Method Details

.item_analysis(directory) ⇒ Object

Create an item analysis table containing average response time and accuracy for each item over all logfiles.



144
145
146
147
148
149
150
151
# File 'lib/logfile.rb', line 144

def self.item_analysis(directory)
  logfiles = Dir.glob(File.join(directory, '*.txt')).collect { |lf| lf = Logfile.new(lf) }
  all_items = self.item_table(logfiles)
  item_groups = self.group_items_by(all_items, ['code1', 'pair_type'])
  summary = self.item_summary(item_groups)
  
  return summary
end

.summarize_directory(directory) ⇒ Object

Create a Ruport::Data::Table containing summary data for a group of Behavioral logfiles. Arguments:

  • directory : String. Path to a directory to summarize.

Raises an IO Error if no logfiles were successfully summarized.

Raises:

  • (IOError)


127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/logfile.rb', line 127

def self.summarize_directory(directory)
  table = Ruport::Data::Table.new
  Dir.glob(File.join(directory, '*.txt')).each do |logfile| 
    # Intialize a logfile without any conditions.
    lf = Logfile.new(logfile)
    table << lf.ruport_summary
    table.column_names = lf.summary_attributes if table.column_names.empty?
  end
  
  # Ensure that at least some logfiles were found and summarized.
  raise IOError, "Couldn't find any logfiles in #{directory}" unless table.length >= 1
  
  return table
end

.write_summary(filename = nil, directory = nil, grouping = nil) ⇒ Object

Write a summary table of logfiles to a CSV Arguments:

  • filename : String. Output Filename for CSV

  • directory : String. Directory to summarize (defaults to pwd).

  • grouping : String. Table attribute to group responses by. (defaults to ‘version’)



107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/logfile.rb', line 107

def self.write_summary(filename = nil, directory = nil, grouping = nil)
  # One usage for this method is from the summarize_responses.rb executible,
  # which doesn't allow for ordered arguments on the fly.  Therefore,
  # assign defaults within the method itself, not the signature.
  filename ||= "logfile_summary.csv"
  directory ||= Dir.pwd
  grouping ||= 'version'
  
  table = self.summarize_directory(directory)
  
  File.open(filename, 'w') do |f| 
    f.puts Ruport::Data::Grouping(table, :by => grouping).to_csv
  end
end

Instance Method Details

#<=>(other_logfile) ⇒ Object

Sort Logfiles by their Modification Time



98
99
100
# File 'lib/logfile.rb', line 98

def <=>(other_logfile)
  File.stat(@textfile).mtime <=> File.stat(other_logfile.textfile).mtime
end

#combine_vectors(combined_vector_title, original_vector_titles) ⇒ Object

Combine vectors into a new one (new_misses + old_misses = misses)



182
183
184
185
186
187
188
# File 'lib/logfile.rb', line 182

def combine_vectors(combined_vector_title, original_vector_titles)
  # Add the combined vectors to the vectors instance variable.
  condition_vectors[combined_vector_title] = combined_vectors(original_vector_titles)
  
  # Add the new condition to @conditions
  @conditions << combined_vector_title
end

#condition_vectorsObject

Raises:

  • (ScriptError)


50
51
52
53
54
55
# File 'lib/logfile.rb', line 50

def condition_vectors
  return @vectors if @vectors
  raise ScriptError, "Conditions must be set to extract vectors" if @conditions.empty?
  vectors = extract_condition_vectors(@conditions)
  @vectors = zero_and_convert_to_reps(vectors)
end

#response_pair_attributesObject

Fields to be included in a Response Pair Table



169
170
171
# File 'lib/logfile.rb', line 169

def response_pair_attributes
  ['enum', 'version', 'ctime', 'pair_type', 'code1', 'time1', 'code2', 'time2', 'time_diff']
end

#response_pairs_tableObject

Create a Ruport::Data::Table of all the response pairs for a given logfile.



154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/logfile.rb', line 154

def response_pairs_table
  response_pairs = []
  
  @textfile_data.each do |line|
    next if line.empty?
    header = line.first.gsub(/(\(|\))/, '_').downcase.chomp("_").to_sym
    if line[1] =~ /(o|n)_\w\d{2}/
      response_pairs << Ruport::Data::Record.new(response_pair_data(line), :attributes => response_pair_attributes)
    end
  end    
  
  return response_pairs
end

#ruport_summaryObject



173
174
175
# File 'lib/logfile.rb', line 173

def ruport_summary
  Ruport::Data::Record.new(summary_data, :attributes => summary_attributes )
end

#summary_attributesObject



177
178
179
# File 'lib/logfile.rb', line 177

def summary_attributes
  ['enum', 'task', 'version', 'ctime'] + @textfile_data[0]
end

#to_csvObject



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/logfile.rb', line 57

def to_csv
  rows = condition_vectors.values
  rows = pad_array(rows)
  
  output = ""
  output <<  vectors.keys.join(', ') + "\n"
  vectors.values.transpose.each do |row|
    output << row.join(', ') + "\n"
  end
  
  return output
end

#write_csv(filename) ⇒ Object

Raises:

  • (ScriptError)


70
71
72
73
74
# File 'lib/logfile.rb', line 70

def write_csv(filename)
  File.open(filename, 'w') { |f| f.puts to_csv }
  raise ScriptError, "Unable to write #{filename}" unless File.exist?(filename)
  @csv_filename = filename
end

#write_mat(prefix) ⇒ Object

Raises:

  • (ScriptError)


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/logfile.rb', line 76

def write_mat(prefix)
  queue = MatlabQueue.new    
  queue.paths << [
    Pathname.new(File.join(File.dirname(__FILE__), 'matlab_helpers')).realpath
  ]
  
  raise ScriptError, "Can't find #{@csv_filename}" unless File.exist?(@csv_filename)

  queue << "prepare_onsets( \
    '#{@csv_filename}', \
    '#{prefix}', \
    { #{@conditions.collect {|c| "'#{c}'"}.join(' ') } } \
  )"
  
  queue.run!
  
  raise ScriptError, "Problem writing #{prefix}.mat" unless File.exist?(prefix + '.mat')
  
  return prefix + '.mat'
end