Class: Mexico::Fiesta::Interfaces::TextGridInterface

Inherits:
Object
  • Object
show all
Includes:
Mexico::FileSystem, Singleton
Defined in:
lib/mexico/fiesta/interfaces/text_grid_interface.rb

Overview

Import and export interface for Praat's text grid format.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.export(doc, io = $stdout, params = {}) ⇒ Object


31
32
33
# File 'lib/mexico/fiesta/interfaces/text_grid_interface.rb', line 31

def self.export(doc, io=$stdout, params = {})
  instance.export(doc, io, params)
end

.import(io = $stdin, params = {}) ⇒ Object


26
27
28
29
# File 'lib/mexico/fiesta/interfaces/text_grid_interface.rb', line 26

def self.import(io=$stdin, params = {})
  puts 'class method import'
  instance.import(io, params)
end

Instance Method Details

#export(doc, io = $stdout, params = {}) ⇒ Object


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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/mexico/fiesta/interfaces/text_grid_interface.rb', line 97

def export(doc, io=$stdout, params = {})
  Mexico::Util::FancyWriter.new(io) do
    line 'File type = "ooTextFile"'
    line 'Object class = "TextGrid"'
    line

    # overall min and max values
    total_item_links = doc.items.collect{|i| i.interval_links}.flatten
    total_min = total_item_links.collect{|l| l.min}.min
    total_max = total_item_links.collect{|l| l.max}.max
    line "xmin = %f" % total_min
    line "xmax = %f" % total_max
    line 'tiers? <exists>'
    line "size = %i" % doc.layers.size
    line 'item []:'
    indent 4 do
      # FOREACH layer : print layer header block
      doc.layers.each_with_index do |layer,layer_index|
        line 'item [%i]:' % (layer_index+1)

        indent 4 do
          # "IntervalTier", "name", min, max, annocount
          line 'class = "IntervalTier"'
          line %Q(name = "#{layer.name}")
          layer_item_links = doc.items.collect{|i| i.interval_links}.flatten
          layer_min = layer_item_links.collect{|l| l.min}.min
          layer_max = layer_item_links.collect{|l| l.max}.max
          line "xmin = %f" % layer_min
          line "xmax = %f" % layer_max

          # FOREACH item in layer : min, max, value
          sorted_items = layer.items.sort{|i,j| i.interval_links.first.min <=> i.interval_links.first.min}
          time_points = [total_min, total_max, layer_min, layer_max]
          sorted_items.each do |i|
            time_points << i.interval_links.first.min
            time_points << i.interval_links.first.max
          end
          time_points.uniq!.sort!
          # print effective number of annotations
          line "intervals: size = %i" % (time_points.size-1)
          time_points.each_with_index do |current_point, n|
            next_point = nil
            unless n == time_points.size-1
              next_point = time_points[n+1]
            end
            unless next_point.nil?
              #puts "-"*48
              #puts "TL:   %20.18f - %20.18f" % [current_point, next_point]
              #sorted_items.each do |it|
              #  puts "IT:   %20.18f - %20.18f  --  %20.18f - %20.18f, %s" % [it.interval_links.first.min, it.interval_links.first.max, (it.interval_links.first.min-current_point), (it.interval_links.first.max-next_point), ((it.interval_links.first.min-current_point).abs<0.00001 && (it.interval_links.first.max-next_point).abs<0.00001)]
              #end
              line 'intervals [%i]:' % (n+1)
              indent 4 do
                item = sorted_items.select{|i| (i.interval_links.first.min-current_point).abs<0.00001 && (i.interval_links.first.max-next_point).abs<0.00001}.first
                #puts item
                line 'xmin = %f' % current_point
                line 'xmax = %f' % next_point
                if item.nil?
                  line 'text = ""'
                else
                  line %Q(text = "#{item.data.string_value}")
                end
              end
            end
          end
        end
      end
    end
  end
end

#import(io = $stdin, params = {}) ⇒ Object


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
# File 'lib/mexico/fiesta/interfaces/text_grid_interface.rb', line 35

def import(io=$stdin, params = {})

  io.rewind

  fdoc = FiestaDocument.new
  timeline = fdoc.add_standard_timeline('s')

  encoding = params.has_key?(:encoding) ? params[:encoding] : 'UTF-16'

  fdoc = FiestaDocument.new
  timeline = fdoc.add_standard_timeline('s')

  fileType = io.gets.strip
  objectClass = io.gets.strip
  io.gets # blank line
  global_min = io.gets.to_f
  global_max = io.gets.to_f
  io.gets # <exists>

  size_spec = io.gets.strip
  size_match = size_spec.match(/\d+/)
  size_spec = size_match[0].to_i if size_match

  io.gets # item container header
  for tier_num in (1..size_spec)
    # read tier item line, drop it
    io.gets # single item header

    tierClass = io.gets.match(/"(.*)"/)[1]
    tierName  = Mexico::Util::strip_quotes(io.gets.match(/"(.*)"/)[1])
    tierXmin = io.gets.match(/(\d+(\.\d+)?)/)[1].to_f
    tierXmax = io.gets.match(/(\d+(\.\d+)?)/)[1].to_f
    tierSize = io.gets.match(/size\s*=\s*(\d+)/)[1].to_i

    # create layer object from that tier
    layer = fdoc.add_layer({identifier:tierName, name:tierName})

    for anno_num in (1..tierSize)
      io.gets
      annoMin = io.gets.match(/(\d+(\.\d+)?)/)[1].to_f
      annoMax = io.gets.match(/(\d+(\.\d+)?)/)[1].to_f
      annoVal = io.gets.match(/"(.*)"/)[1]
      if annoVal.strip != ""
        item = fdoc.add_item({identifier:"l#{tier_num}a#{anno_num}"}) do |i|
          i.add_interval_link IntervalLink.new(
                                  identifier:"#{i.identifier}-il",
                                  min: annoMin,
                                  max: annoMax,
                                  target_object: timeline )
          i.data = Mexico::FileSystem::Data.new(string_value: annoVal)
          i.add_layer_link LayerLink.new(
                               identifier:"#{i.identifier}-ll",
                               target_object: layer )
        end
        # puts item
      end
    end
  end
  fdoc
end