Class: NexusParser::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/nexus_parser.rb

Overview

constructs the NexusParser

Instance Method Summary collapse

Constructor Details

#initializeBuilder

Returns a new instance of Builder.



124
125
126
# File 'lib/nexus_parser.rb', line 124

def initialize
  @nf = NexusParser.new
end

Instance Method Details

#add_note(options = {}) ⇒ Object



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/nexus_parser.rb', line 245

def add_note(options = {})
  @opt = {
    :text => ''
  }.merge!(options)

  case @opt[:type]

  # Why does mesquite differentiate b/w footnotes and annotations?!, apparently same data structure?
  when 'TEXT' # a footnote
    if @opt[:file]
     @nf.notes << NexusParser::Note.new(@opt)

    elsif  @opt[:taxon] && @opt[:character] # its a cell, parse this case
      @nf.codings[@opt[:taxon].to_i - 1][@opt[:character].to_i - 1].notes = [] if !@nf.codings[@opt[:taxon].to_i - 1][@opt[:character].to_i - 1].notes
      @nf.codings[@opt[:taxon].to_i - 1][@opt[:character].to_i - 1].notes << NexusParser::Note.new(@opt)

    elsif @opt[:taxon] && !@opt[:character]
      @nf.taxa[@opt[:taxon].to_i - 1].notes << NexusParser::Note.new(@opt)

    elsif @opt[:character] && !@opt[:taxon]

      @nf.characters[@opt[:character].to_i - 1].notes << NexusParser::Note.new(@opt)
    end

  when 'AN' # an annotation, rather than a footnote, same dif
    if @opt[:t] && @opt[:c]
      @nf.codings[@opt[:t].to_i - 1][@opt[:c].to_i - 1].notes = [] if !@nf.codings[@opt[:t].to_i - 1][@opt[:c].to_i - 1].notes
      @nf.codings[@opt[:t].to_i - 1][@opt[:c].to_i - 1].notes << NexusParser::Note.new(@opt)
    elsif @opt[:t]
      @nf.taxa[@opt[:t].to_i - 1].notes << NexusParser::Note.new(@opt)
    elsif @opt[:c]
      @nf.characters[@opt[:c].to_i - 1].notes << NexusParser::Note.new(@opt)
    end
  end

end

#add_var(hash) ⇒ Object



162
163
164
165
166
167
# File 'lib/nexus_parser.rb', line 162

def add_var(hash)
  hash.keys.each do |k|
    raise "var #{k} has already been set" if @nf.vars[:k]
  end
  @nf.vars.update(hash)
end

#code_row(taxon_index, rowvector) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/nexus_parser.rb', line 138

def code_row(taxon_index, rowvector)

  @nf.characters.each_with_index do |c, i|
    raise(ParseError,
      "Row #{taxon_index} of the matrix is too short") if rowvector[i].nil?

    @nf.codings[taxon_index.to_i] = [] if !@nf.codings[taxon_index.to_i]
    @nf.codings[taxon_index.to_i][i] = NexusParser::Coding.new(:states => rowvector[i])

    # !! we must update states for a given character if the state isn't found (not all states are referenced in description !!

    existing_states = @nf.characters[i].state_labels

    new_states = rowvector[i].class == Array ? rowvector[i].collect{|s| s.to_s} :  [rowvector[i].to_s]
    new_states.delete("?") # we don't add this to the db
    new_states = new_states - existing_states

    new_states.each do |s|
      @nf.characters[i].add_state(:label => s)
    end

  end
end

#create_or_update_states_for_character(i, options) ⇒ Object



223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/nexus_parser.rb', line 223

def create_or_update_states_for_character(i, options)
  options.keys.each do |k|

    if (@nf.characters[i].states != {}) && @nf.characters[i].states[k] # state exists

      ## !! ONLY HANDLES NAME, UPDATE TO HANDLE notes etc. when we get them ##
      update_state(i, :index => k, :name => options[k])

    else # doesn't, create it
      @nf.characters[i].add_state(:label => k.to_s, :name => options[k])
    end
  end
end

#nexus_fileObject



282
283
284
# File 'lib/nexus_parser.rb', line 282

def nexus_file
  @nf
end

#stub_chrObject



133
134
135
136
# File 'lib/nexus_parser.rb', line 133

def stub_chr
  @nf.characters.push(NexusParser::Character.new)
  return @nf.characters.size
end

#stub_taxonObject



128
129
130
131
# File 'lib/nexus_parser.rb', line 128

def stub_taxon
  @nf.taxa.push(NexusParser::Taxon.new)
  return @nf.taxa.size
end

#update_chr(options = {}) ⇒ Object

legal hash keys are :index, :name, and integers that point to state labels

Raises:



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/nexus_parser.rb', line 178

def update_chr(options = {} )
  @opt = {
    :name => ''
  }.merge!(options)
  return false if !@opt[:index]

  @index = @opt[:index].to_i

  # need to create the characters

  raise(ParseError, "Can't update character of index #{@index}, it doesn't exist! This is a problem parsing the character state labels. Check the indices. It may be for this character \"#{@opt[:name]}\".") if !@nf.characters[@index]

  (@nf.characters[@index].name = @opt[:name]) if @opt[:name]

  @opt.delete(:index)
  @opt.delete(:name)

  # the rest have states
  create_or_update_states_for_character(@index, @opt)
end

#update_chr_name(i, name) ⇒ Object

Raises:



199
200
201
202
203
204
205
# File 'lib/nexus_parser.rb', line 199

def update_chr_name(i, name)
  raise(ParseError, "There are #{@nf.characters.count} characters but we're trying to update from row #{i + 1} of the CHARLABELS list - check your NCHAR and/or the length of your list.") if !@nf.characters[i]

  # The CHARLABELS list is unindexed, so users are allowed to use '_' to
  # indicate that a character name is unspecified.
  @nf.characters[i].name = (name == '_' ? '' : name)
end

#update_chr_states(options = {}) ⇒ Object

legal hash keys are :index and integers that point to state labels

Raises:



208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/nexus_parser.rb', line 208

def update_chr_states(options = {})
  return false if !options[:index]

  @opt = options

  @index = @opt[:index].to_i

  raise(ParseError, "Can't update character of index #{@index}, it doesn't exist! This is a problem parsing the STATELABELS. Check the indices.") if !@nf.characters[@index]

  @opt.delete(:index)

  # the rest have states
  create_or_update_states_for_character(@index, @opt)
end

#update_state(chr_index, options = {}) ⇒ Object



237
238
239
240
241
242
243
# File 'lib/nexus_parser.rb', line 237

def update_state(chr_index, options = {})
  # only handling name now
  #options.keys.each do |k|
    @nf.characters[chr_index].states[options[:index]].name = options[:name]
      # add notes here
  # end
end

#update_taxon(options = {}) ⇒ Object



169
170
171
172
173
174
175
# File 'lib/nexus_parser.rb', line 169

def update_taxon(options = {})
  @opt = {
    :name => ''
  }.merge!(options)
  return false if !@opt[:index]
  (@nf.taxa[@opt[:index]].name = @opt[:name]) if @opt[:name]
end