Advertisement
Guest User

Untitled

a guest
Apr 28th, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.57 KB | None | 0 0
  1. #!/usr/bin/env ruby
  2. # frozen_string_literal: true
  3.  
  4. require 'csv'
  5.  
  6. MATCHER = /\Adata\/(?<deg>\d+)\/(?<bug>L\d)\.txt\z/.freeze
  7.  
  8. files = Hash.new { |h, k| h[k] = Hash.new }
  9.  
  10. Dir['data/*/*.txt'].each do |s|
  11. match = s.match(MATCHER)
  12. files[match['deg']][match['bug'].to_sym] = {file: s}
  13. end
  14.  
  15. class Point < Struct.new(:t, :x, :y)
  16. def self.average(points)
  17. Point.new(*points.map(&:to_a).transpose.map{|x| x.reduce(0.0, :+) / points.length})
  18. end
  19.  
  20. def distance(point)
  21. Math.sqrt((x - point.x) ** 2 + (y - point.y) ** 2)
  22. end
  23. end
  24.  
  25. files.each do |temp, bugs|
  26. bugs.each do |bug, info|
  27. info[:total] = 0
  28. info[:total_reg] = 0
  29. info[:start] = nil
  30. CSV.foreach(info[:file], skip_lines: /^L\d/, headers: true, col_sep: "\t", converters: [:float]).each_cons(3).map do |rows|
  31. info[:total_reg] += Point.new(*rows.first.fields).distance(Point.new(*rows[1].fields))
  32. Point.average(rows.map do |r|
  33. Point.new(*r.fields('t', 'x', 'y'))
  34. end)
  35. end.each_cons(2) do |p1, p2|
  36. info[:start] ||= p1.t
  37. info[:total] += p1.distance(p2)
  38. info[:end] = p2.t
  39. end
  40. info[:time] = info[:end] - info[:start]
  41. info[:speed] = info[:total] / info[:time]
  42. puts "#{temp} #{bug} #{info[:total] / info[:time]}"
  43. end
  44. end
  45.  
  46. tab = CSV.generate(col_sep: ',', headers: ['Temp', 'Bug', 'Distance', 'Time', 'Speed'], write_headers: true) do |t|
  47. files.each do |temp, bugs|
  48. bugs.each do |bug, info|
  49. row = [temp, bug] + info.values_at(:total, :time, :speed).map{|v| "%6.5e" % v}
  50. t.add_row(row)
  51. end
  52. end
  53. end
  54.  
  55. File.open('output.csv', 'w') {|f| f.write(tab)}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement